0

I have following classes:

public class Entity {

@Id 
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private String name;

@JsonManagedReference
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Category category;

//Constructors, getters and setters
}


public class Category {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private String name;

@JsonBackReference
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Entity> entity;

//Constructors, getters and setters
}

I have a form where when I submit the form I get following JSON:

{
 id: "1"
 name: "EntityA"
 category: {    
    id: "4"
    name: "categoryA"
 }
}

CategoryA is already in database. When I persist EntityA object (main object) to database BOTH objects will be persisted.

What's wrong with it?

Problem is that category is going to be persisted again with same information but with different id. So when I persist the above object EntityA is persisted fine in database, but category is persisted again with different id even if it exist in database.

So here's the steps with databse point of view.

Initial database:

Entity table (empty)

|id | name | category_id |
--------------------------
|   |      |             |

Category table

| id | name    |
----------------
|  4 |categoryA|

Entity_category table (empty)

| entity_id | category_id |
---------------------------
|           |             | 

After persisting

Entity table (empty)

id | name  | category_id |
--------------------------
 1 |EntityA| 5           |

Entity_category table (should not be empty, but is empty)

| entity_id | category_id |
---------------------------
|           |             | 

Category table

id | name    |
--------------
 4 |categoryA|
 5 |categoryA|

What I want is simply when I persist the object of EntityA it won't persist category, but instead it updates it's relationship with EntityA. After persisting the category_id of the second view should be 4 instead of 5.

I use entity manager's persist() method to persist the objects.

Technologies I use are jackson 2.0, Hibernate, Postgres as database.

I have also tested @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") annotation above both classes but it doesn't help.

What I'm doing wrong here? Any help is appreciated.

3 Answers 3

2

You have not marked Id as primary key (@Id) into your entities. In your case it seems that id is an auto-increment column (that's why id is different from what you have inserted) and JPA is not able to detect that the object is the same one. Try to mark ID fields with annotation @Id @GeneratedValue and try again.

Sign up to request clarification or add additional context in comments.

10 Comments

Also I have noticed that you have ManyToOne-OneToMany relationship with these entities. I don't think that U need extra join table (Entity_category) with this kind of relationship. JPA will not use it either
sorry I forgot to add that. It is already in my code. I will add it now here. Thanks for pointing it out.
Those annotations won't help. Same problem still occurs.
Why don't U use merge instead of persist? In this case It will act as SaveOrUpdate
Same problem occures, it won't help with merging either.
|
0

Okay so I finally found the solution. The whole problem was because I had in the json category object key "id" which was written with small "I" letter, which means that it can't find the category id, because it doesn't match the Id field of entity class thus producing a category with null id. This is why it persisted the category as new entity because it couldn't find such object in database after deserialization process.

Make sure that when you persist your json object, every key in the json must match exactly your entity class fields or attributes.

Comments

-1

Try getting a reference to the category and set the reference manually before committing/merging (if it is found in the database):

Category category = em.find(Category.class, entity.getCategory().getId());
if (category!=null){
  entity.setCategory(category);
}

This way category will be an attached object.

4 Comments

This doesn't help anything.
Yes but remember that you get the object in json form which means that the code you have added above need deserialization of the json object in order to use it properly in java. Which again means that more logic for desrialization is required. For example you search for proper category by using its id. Category id is in the json object.
I agree with you, this is what I had in mind when I posted the solution. The specific solution has to be done in two steps. Deserialise and then attach the category object. It is not a one step solution.
Check this link for tips: stackoverflow.com/questions/17874688/….

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.