I am trying to run this basic JPA/EJB code:
public static void main(String[] args){
UserBean user = new UserBean();
user.setId(1);
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
I get this error:
javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database
Any ideas?
I search on the internet and the reason I found was:
This was caused by how you created the objects, i.e. If you set the ID property explicitly. Removing ID assignment fixed it.
But I didn’t get it, what will I have to modify to get the code working?
asked Mar 14, 2010 at 8:25
The error occurs because the object’s ID is set. Hibernate distinguishes between transient and detached objects and persist
works only with transient objects. If persist
concludes the object is detached (which it will because the ID is set), it will return the «detached object passed to persist» error. You can find more details here and here.
However, this only applies if you have specified the primary key to be auto-generated: if the field is configured to always be set manually, then your code works.
answered Mar 14, 2010 at 11:44
3
Let’s say you have two entities Album
and Photo
. Album contains many photos, so it’s a one to many relationship.
Album class
@Entity
public class Album {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Integer albumId;
String albumName;
@OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true)
Set<Photo> photos = new HashSet<Photo>();
}
Photo class
@Entity
public class Photo{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Integer photo_id;
String photoName;
@ManyToOne(targetEntity=Album.class)
@JoinColumn(name="album_id")
Album album;
}
What you have to do before persist or merge is to set the Album reference in each photos.
Album myAlbum = new Album();
Photo photo1 = new Photo();
Photo photo2 = new Photo();
photo1.setAlbum(myAlbum);
photo2.setAlbum(myAlbum);
That is how to attach the related entity before you persist or merge.
answered Feb 5, 2011 at 5:00
zawhtutzawhtut
8,3555 gold badges52 silver badges76 bronze badges
2
remove
user.setId(1);
because it is auto generate on the DB,
and continue with persist command.
answered Apr 20, 2011 at 7:27
I got the answer, I was using:
em.persist(user);
I used merge in place of persist:
em.merge(user);
But no idea, why persist didn’t work.
answered Mar 14, 2010 at 9:07
zengrzengr
38.4k37 gold badges130 silver badges192 bronze badges
3
if you use to generate the id = GenerationType.AUTO
strategy in your entity.
Replaces user.setId (1)
by user.setId (null)
, and the problem is solved.
j0k
22.6k28 gold badges79 silver badges90 bronze badges
answered Aug 24, 2012 at 4:49
Here .persist() only will insert the record.If we use .merge() it will check is there any record exist with the current ID, If it exists, it will update otherwise it will insert a new record.
SkyWalker
28.4k14 gold badges74 silver badges132 bronze badges
answered Jul 16, 2012 at 14:41
PSRPSR
39.8k42 gold badges112 silver badges151 bronze badges
1
I know its kind of too late and proly every one got the answer. But little bit more to add to this: when GenerateType is set, persist() on an object is expected to get an id generated.
If there is a value set to the Id by user already, hibernate treats it as saved record and so it is treated as detached.
if the id is null — in this situation a null pointer exception is raised when the type is AUTO or IDENTITY etc unless the id is generated from a table or a sequece etc.
design: this happens when the table has a bean property as primary key.
GenerateType must be set only when an id is autogenerated.
remove this and the insert should work with the user specified id.
(it is a bad design to have a property mapped to primary key field)
answered Jul 5, 2012 at 21:08
haripriyaharipriya
511 silver badge1 bronze badge
If you set id in your database to be primary key and autoincrement, then this line of code is wrong:
user.setId(1);
Try with this:
public static void main(String[] args){
UserBean user = new UserBean();
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
answered Feb 28, 2016 at 11:47
NemusNemus
3,89912 gold badges38 silver badges57 bronze badges
1
I had this problem and it was caused by the second level cache:
- I persisted an entity using hibernate
- Then I deleted the row created from a separate process that didn’t interact with the second level cache
- I persisted another entity with the same identifier (my identifier values are not auto-generated)
Hence, because the cache wasn’t invalidated, hibernate assumed that it was dealing with a detached instance of the same entity.
answered Mar 11, 2011 at 15:55
hertzsprunghertzsprung
9,4654 gold badges43 silver badges77 bronze badges
You can assign ID and then persist an entity, if, for example, your ID is represented by email of a user. But, to make it work, you need to make sure that your ID field doesn’t have @GeneratedValue set.
For example, this code will raise an exception if you have this Entity with the email ID field and @GeneratedValue set:
public class UserEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "email")
private String email;
...
}
and try to persist such an object:
UserEntity user = new UserEntity();
user.setEmail(email);
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
so, in order to make it work, you need to remove the @GeneratedValue, but keep the @ID:
public class UserEntity {
@Id
@Column(name = "email")
private String email;
...
}
answered Aug 19 at 15:01
I am trying to run this basic JPA/EJB code:
public static void main(String[] args){
UserBean user = new UserBean();
user.setId(1);
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
I get this error:
javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database
Any ideas?
I search on the internet and the reason I found was:
This was caused by how you created the objects, i.e. If you set the ID property explicitly. Removing ID assignment fixed it.
But I didn’t get it, what will I have to modify to get the code working?
asked Mar 14, 2010 at 8:25
The error occurs because the object’s ID is set. Hibernate distinguishes between transient and detached objects and persist
works only with transient objects. If persist
concludes the object is detached (which it will because the ID is set), it will return the «detached object passed to persist» error. You can find more details here and here.
However, this only applies if you have specified the primary key to be auto-generated: if the field is configured to always be set manually, then your code works.
answered Mar 14, 2010 at 11:44
3
Let’s say you have two entities Album
and Photo
. Album contains many photos, so it’s a one to many relationship.
Album class
@Entity
public class Album {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Integer albumId;
String albumName;
@OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true)
Set<Photo> photos = new HashSet<Photo>();
}
Photo class
@Entity
public class Photo{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Integer photo_id;
String photoName;
@ManyToOne(targetEntity=Album.class)
@JoinColumn(name="album_id")
Album album;
}
What you have to do before persist or merge is to set the Album reference in each photos.
Album myAlbum = new Album();
Photo photo1 = new Photo();
Photo photo2 = new Photo();
photo1.setAlbum(myAlbum);
photo2.setAlbum(myAlbum);
That is how to attach the related entity before you persist or merge.
answered Feb 5, 2011 at 5:00
zawhtutzawhtut
8,3555 gold badges52 silver badges76 bronze badges
2
remove
user.setId(1);
because it is auto generate on the DB,
and continue with persist command.
answered Apr 20, 2011 at 7:27
I got the answer, I was using:
em.persist(user);
I used merge in place of persist:
em.merge(user);
But no idea, why persist didn’t work.
answered Mar 14, 2010 at 9:07
zengrzengr
38.4k37 gold badges130 silver badges192 bronze badges
3
if you use to generate the id = GenerationType.AUTO
strategy in your entity.
Replaces user.setId (1)
by user.setId (null)
, and the problem is solved.
j0k
22.6k28 gold badges79 silver badges90 bronze badges
answered Aug 24, 2012 at 4:49
Here .persist() only will insert the record.If we use .merge() it will check is there any record exist with the current ID, If it exists, it will update otherwise it will insert a new record.
SkyWalker
28.4k14 gold badges74 silver badges132 bronze badges
answered Jul 16, 2012 at 14:41
PSRPSR
39.8k42 gold badges112 silver badges151 bronze badges
1
I know its kind of too late and proly every one got the answer. But little bit more to add to this: when GenerateType is set, persist() on an object is expected to get an id generated.
If there is a value set to the Id by user already, hibernate treats it as saved record and so it is treated as detached.
if the id is null — in this situation a null pointer exception is raised when the type is AUTO or IDENTITY etc unless the id is generated from a table or a sequece etc.
design: this happens when the table has a bean property as primary key.
GenerateType must be set only when an id is autogenerated.
remove this and the insert should work with the user specified id.
(it is a bad design to have a property mapped to primary key field)
answered Jul 5, 2012 at 21:08
haripriyaharipriya
511 silver badge1 bronze badge
If you set id in your database to be primary key and autoincrement, then this line of code is wrong:
user.setId(1);
Try with this:
public static void main(String[] args){
UserBean user = new UserBean();
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
answered Feb 28, 2016 at 11:47
NemusNemus
3,89912 gold badges38 silver badges57 bronze badges
1
I had this problem and it was caused by the second level cache:
- I persisted an entity using hibernate
- Then I deleted the row created from a separate process that didn’t interact with the second level cache
- I persisted another entity with the same identifier (my identifier values are not auto-generated)
Hence, because the cache wasn’t invalidated, hibernate assumed that it was dealing with a detached instance of the same entity.
answered Mar 11, 2011 at 15:55
hertzsprunghertzsprung
9,4654 gold badges43 silver badges77 bronze badges
You can assign ID and then persist an entity, if, for example, your ID is represented by email of a user. But, to make it work, you need to make sure that your ID field doesn’t have @GeneratedValue set.
For example, this code will raise an exception if you have this Entity with the email ID field and @GeneratedValue set:
public class UserEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "email")
private String email;
...
}
and try to persist such an object:
UserEntity user = new UserEntity();
user.setEmail(email);
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
so, in order to make it work, you need to remove the @GeneratedValue, but keep the @ID:
public class UserEntity {
@Id
@Column(name = "email")
private String email;
...
}
answered Aug 19 at 15:01
Detached entity passed to persist exception or its variations like spring detached entity passed to persist can come up in various situations, among which persisting an entity that is already present in your database ranks at the top.
The term “detached entity” in the exception statement refers to an entity already residing in the database because you have persisted the same earlier. Now, this post will state the different causes of the given exception and help you normalize the problematic situations to make your code work again.
After reading this article, you’ll be aware of the next step that’ll eliminate the same exception permanently.
Contents
- What Invites the Detached Entity Passed To Persist Exception?
- – You Are Trying To Persist an Already Persisted Entity
- – You Are Having a Setter While Persisting an Entity
- – You Are Setting an ID for an Entity While It’s Auto-generated
- – Your equals() Method Has a Child Collection
- How To Save Yourself from the Detached Entity Passed To Persist Exception?
- – Choose Merge Over Persist or All
- – Avoid Specifying Cascading With the Child Entity
- – Remove the Setters
- – Don’t Set the ID When It’s Not Required
- – Never Pass a Child Collection To the equals() Method
- FAQ
- 1. How Can You Make a Detached Entity Persistent Again?
- 2. How Would You Differentiate Between Persist and Merge?
- 3. How Is save() Different from persist() in Hibernate?
- 4. What Are the Transient and Persistent Objects?
- 5. Which Methods Should You Call To Make the Objects Persistent?
- Conclusion
What Invites the Detached Entity Passed To Persist Exception?
Your attempt to persist an already persisted entity can invite the spring data jpa detached entity passed to persist exception to your system. Plus, assigning a value to an auto-generated column, having setters while persisting an entity, or passing a child collection to the equals() function also causes this error.
– You Are Trying To Persist an Already Persisted Entity
Trying to persist an already persisted entity can make the detached entity passed to persist test exception pop up on your screen. The reason is simple. You can not add an already existing entity to the database. However, you can always update it or add more details to it.
For example, you have created the student and teacher entities. The given entities have many-to-one relationships between them. The idea is based on a real-world concept pointing toward a single teacher teaching many students, and every student is taught by one teacher. Next, you have created a teacher object, assigned multiple students to it, and persisted the same object.
Until this step, everything worked fine. Later, you tried to create an object of the student entity, which has a many-to-one relationship with the teacher entity.
But the moment you try to persist the student object, you’ll get the detached entity passed to persist many-to-one exception disallowing the student object to persist. It is because persisting the student object will also persist the already persisted teacher object, which is not acceptable and impossible.
The reference code showing the entities has been attached below.
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(cascade = {CascadeType.ALL})
Private Teacher byTeacher;
….
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(cascade = {CascadeType.ALL},fetch= FetchType.EAGER, mappedBy = “byTeacher”)
private Set<Student> students;
– You Are Having a Setter While Persisting an Entity
You aren’t allowed to have setters for an entity if you plan to persist the same. If you try to set a value for an entity, such as an id, while persisting it, you’ll receive the invaliddataaccessapiusageexception: detached entity passed to persist exception. In short, you can’t set values and persist an entity simultaneously.
For example, you have created an id setter for your employee entity. Now, you want to persist the given entity. Here, the setter will come in the way, pose a hurdle in persisting the employee entity, and result in the same exception.
– You Are Setting an ID for an Entity While It’s Auto-generated
Setting an id or primary key manually while you have switched on its auto-generation setting will bring you closer to the detached entity passed to persist entitymanager exception. It is because the columns with auto-generation settings do not require you to pass values to them.
Imagine having an id column for the books entity in the database. You have specified GenerationType.AUTO for the ID column. Now, if you try to set an id while creating a books object. You’ll end up receiving the stated exception.
The code snippet aligning with the above example is attached here.
@Entity
@Table(name = “Books”)
public class Book {
@Id
@GeneratedValue
private Long id;
private String name;
private String author;
}
Book book1 = new Book(1, “myBook”, “Anonymous”);
testEntityManager.persist(book1);
– Your equals() Method Has a Child Collection
Passing a child collection to the equals() method will make hibernate assume that every element specified for the child collection is a new object that needs to be persisted instead of an updated value for the existing one. This misassumption might result in the same exception.
Think about it this way. You have an organization entity as a parent entity and an employee entity as a child entity. Now, if you try to run the equals() function with the employee collection, you’ll see the given exception on your screen.
The following block of code depicts the same scenario.
public class Organization {
private Long id;
private String orgName;
private Set<Employee> employees;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Organization))
return false;
Organization obj1 = (Organization) obj;
return Objects.equals(this.id, obj1.id)
&& Objects.equals(this.orgName, other.orgName)
&& Objects.equals(this.employees, other.employees);
}
}
How To Save Yourself from the Detached Entity Passed To Persist Exception?
You can save yourself from the detached entity passed to persist exception by merging the entity that is already persisted, not specifying cascading with the child entity, or removing the setters while persisting an entity. Also, passing null to the auto-generated column can fix the issue.
– Choose Merge Over Persist or All
If the cause of the issue is persisting an already persisted entity, use CascadeType.MERGE instead of CascadeType.PERSIST or CascadeType.ALL with @ManyToOne to make things work for you. It means you should merge the persisted entity instead of persisting it again.
Talking about the example entities discussed above, you should replace CascadeType.ALL following @ManyToOne in the student entity with CascadeType.MERGE. It will ensure that the teacher entity is merged when persisting a student object. Consequently, the given exception will leave your screen too. Here is how the altered student entity should look.
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(cascade = {CascadeType.MERGE})
Private Teacher byTeacher;
– Avoid Specifying Cascading With the Child Entity
If you don’t want to use merge cascading with your child entity, then you might like to skip the cascading type. It will ensure that no action in the database affects the parent entity, which is mostly persisted already. Eventually, you’ll never receive the above exception on your screen.
So, you can alter the student entity as shown below.
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
Private Teacher byTeacher;
– Remove the Setters
It would be best to remove any related setters while persisting an entity to get rid of the detached entity passed to persist panache exception. This way, the setters won’t interrupt the process, and your desired operation will be carried out perfectly. For the previous example, you can remove the id setter to settle things.
Deleting the setters is one of the simplest solutions, which will work like magic to eliminate the exception.
– Don’t Set the ID When It’s Not Required
If your id or primary key column is auto-generated, you should not pass an id while creating an object. You can specify null instead of an actual id to let the auto-generated value fit in and remove the said exception from your system.
Considering the Book entity example again, it would be best to create the object like Book book1 = new Book(null, “myBook”, “Anonymous”). Eventually, null will be replaced with an auto-generated id, and the book1 object will be created successfully with a valid id.
– Never Pass a Child Collection To the equals() Method
You should never pass a child collection to the equals() method to avoid hibernate make any misassumptions regarding the given collection. Once everything is clear to hibernate, the exception will disappear from your system. However, please remember that this solution is applied only in relevant cases.
Joining the thread with the previous example, you should remove the coding statement that calls the equals() function with the employee collection. It will help remove the said exception.
FAQ
1. How Can You Make a Detached Entity Persistent Again?
You can make a detached entity persistent again by using the update method of the session. The update method will force an update operation to be executed for the passed object. As the object is originally detached, Hibernate adds this object to the persistence context to make it persistent.
2. How Would You Differentiate Between Persist and Merge?
The difference between persist and merge is that persist should be called only on new entities, while the merge is used to reattach the detached entities. Contrary to the above situations, using merge instead of persist will cause a redundant SQL statement while using the assigned generator.
3. How Is save() Different from persist() in Hibernate?
The save() method is different from the persist() method in hibernate in a way that the save() method lets you assign the identifier value immediately. However, the persist() method fails to confirm the assignment of an identifier value to its persistent state instantly.
4. What Are the Transient and Persistent Objects?
The transient objects are the ones that haven’t been saved yet. It means all of the newly created entities are transient until you persist them. On the other hand, the persistent objects are the ones that have been saved to the database. Entities received from the repository are persistent objects.
5. Which Methods Should You Call To Make the Objects Persistent?
There are a variety of methods you can call to send the objects to the persistent state. The common methods include session.save(e), session.update(e), session.persist(e), session.lock(e), session.saveOrUpdate(e), and session.merge(e). You can execute the one that fits to your need.
Conclusion
The PersistentObjectException: detached entity passed to persist can result from persisting an already persistent entity or setting values for its auto-generated columns. In rare cases, the equals() function with a child collection as an argument can be problematic and result in the said exception. Here you go with a list of solutions extracted from the above post that’ll help you fix the given exception instantly.
- Merge the persisted entity instead of persisting it again to resolve the exception.
- Don’t specify any cascading type with the child entity to stay away from the exception.
- Never provide a value for a column that’ll have its values auto-generated to avoid confusion and, eventually, the exception.
- Ensure to have zero setters while persisting an entity to avoid the said exception.
- Don’t pass a child collection to the equals() function to push away the same exception.
Lastly, remember that the more you know about the dos and don’ts of working with the entities and persisting them, the fewer times you’ll encounter the given exception.
- Author
- Recent Posts
Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team
In this article we are going to discuss the error about Hibernate Detached Entity Passed to Persist. Which is an error that occurs when trying to save an entity considered detached.
Let’s start by understanding what detached entities are.
Starting from Spring Boot 3 and Spring Framework 6, the error: org.hibernate.PersistentObjectException: detached entity passed to persist becomes the following org.hibernate.PersistentObjectExceptionto JPA
PersistenceException`: detached entity passed to persist.
What is a Detached Entity?
In the life cycle of entities in Hibernate, we go through 4 states, transient, managed, detached, and deleted.
A detached Entity is one of the Hibernate states. A detached entity is a POJO whose value corresponds to a row in the database.
We cause the entity to become detached when we close the session used to load it or when we call Session.clear() or Session.evict().
Why do we get the Detached Entity Passed to Persist exception?
The exception “org.hibernate.PersistentObjectException: detached entity passed to persist” or “org.hibernate.PersistentObjectExceptionto JPA
PersistenceException`: detached entity passed to persist” occurs when the session used to load the entity has been closed or Session.clear() or Session.evict() has been used.
Let’s see how we can cause the org.hibernate.PersistentObjectException: detached entity passed to persist exception based on a DepartmentEntity entity.
@Getter @Setter @Entity public class SingleDepartment { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; }
Let’s create a test based on the previous entity to cause the Hibernate exception: org.hibernate.PersistentObjectException: detached entity passed to persist:
@Test public void given_department_when_detach_a_single_to_change_name_then_exception() { singleDepartment = new SingleDepartment(); singleDepartment.setName("Accounts"); session.persist(singleDepartment); session.evict(singleDepartment); singleDepartment.setName("Accounts exception"); session.getTransaction().commit(); assertThatThrownBy(() -> session.persist(singleDepartment)).isInstanceOf( PersistenceException.class).hasMessageContaining( "org.hibernate.PersistentObjectException` to JPA `PersistenceException` : detached entity passed to persist: com.refactorizando.example.detachentity.entity.SingleDepartment"); }
How to fix the Detached Entity Passed to Persist exception?
Fix Hibernate’s detached entity passed to persist error by checking entity state and using correct Cascade type/method.
To fix it, we can use the following options that belong to JPA:
- Merge
Save: Deprecated starting from Spring Boot 3.SaveOrUpdate: Deprecated starting from Spring Boot 3.
@Test public void given_department_when_detach_a_single_entity_with_merge_then_saved() { singleDepartment = new SingleDepartment(); singleDepartment.setName("Accounts"); session.persist(singleDepartment); session.evict(singleDepartment); singleDepartment.setName("Accounts exception"); singleDepartment.setId(1L); session.merge(singleDepartment); session.getTransaction().commit(); Query querySaved = session.createQuery("Select e from SingleDepartment e where id= 1", SingleDepartment.class); singleDepartment = (SingleDepartment) querySaved.getSingleResult(); assertTrue("Accounts exception".equalsIgnoreCase(singleDepartment.getName())); }
Within the session class, we can see two more approaches like Persist and Merge that do not belong to JPA, so it is better to avoid them to use JPA’s own methods.
Detached Entity Passed to Persist exception with OneToMany relationship
Let’s continue with the Department example and let’s associate an Employee with a 1 .. N relationship.
@Getter @Setter @Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; }
And now the Employee entity:
@Getter @Setter @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; @ManyToOne private Department department; }
Relationship uses Merge cascade type (CascadeType.Merge) to propagate merge operations only to the department.
Persisting employee requires prior merge on department in this approach.
@Test public void given_department_when_detach_a_employee_with_merge_then_saved() { Employee employee = new Employee(); employee.setName("Noel"); Department departmentMerge = session.merge(this.department); employee.setDepartment(departmentMerge); session.persist(employee); session.getTransaction().commit(); List<Employee> employees = session.createQuery("Select c from Employee c", Employee.class) .list(); assertEquals(employees.size(), 1); assertTrue(employees.get(0).getName().equalsIgnoreCase("Noel")); }
It should be noted that using persist in the relationship, if we apply Cascade ALL, will throw the exception: org.hibernate.PersistentObjectException: detached entity passed to persist, as we need to perform a merge on the entity first.
If, in the relationship between department and employee, we use persist instead of merge, we will get the error org.hibernate.PersistentObjectException to JPA PersistenceException: detached entity passed to persist:
@Test public void given_a_department_persist_when_new_employee_is_persist_then_exception_is_thrown() { department = new Department(); department.setName("Accounts"); session.persist(department); session.evict(department); department.setId(1L); Employee employee = new Employee(); employee.setDepartment(department); session.persist(employee); assertThatThrownBy(() -> session.persist(department)).isInstanceOf(PersistenceException.class) .hasMessageContaining( "org.hibernate.PersistentObjectException` to JPA `PersistenceException` : detached entity passed to persist: com.refactorizando.example.detachentity.entity.Department"); session.remove(employee); }
Conclusión
The title of this article Error in Hibernate Detached Entity Passed to Persist is a very common error that can occur in our applications with Hibernate. Knowing the different states and the lifecycle of Hibernate will help us better understand Hibernate errors.
In the case of Detached Entity, we will have to see how we are saving the entity or if we have closed the session before saving it, so we will have to use merge.
If you want to see an example where this error occurs, you can take a look at our Github.
If you need more information, you can leave us a comment or send an email to refactorizando.web@gmail.com You can also contact us through our social media channels on Facebook or twitter and we will be happy to assist you!!
Ошибка:
org.hibernate.PersistentObjectException: detached entity passed to persist
Пример, когда может возникать этот эксепшн:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Id @Column(name = «id») @GeneratedValue(strategy = GenerationType.IDENTITY) // commented for manually set the id private long id; @Column(name = «login», unique = true, updatable = false) private String name; //Important to Hibernate! @SuppressWarnings(«MySQLConfig») public UsersDataSet() { } @SuppressWarnings(«MySQLConfig») public UsersDataSet(long id, String name) { this.setId(id); this.setName(name); } public UsersDataSet(String name) { this.setId(—1); this.setName(name); } |
Если не убрать строчку выбора стратегии создания id в автоматическом режиме, то возникнет вышеописанное исключение.
@GeneratedValue(strategy = GenerationType.IDENTITY) |
Причина заключается в том, что запись выше указывает JPA стратегию автоматического создания идентификатора при сохранении (создании) сущности. Однаков в конструкторе уже прописано, что нужно вставить идентификатор вручную. В результате, т.к. индентификатор назначается вручную в конструкторе и отсутствует, то JPA думает, что сохраняется объект, отсутствующий в контексте персистентности (detached from persistence context).
Для исправления либо убирайте в констркуторе указание id, либо убирайте GeneratedValue(strategy = …)
public UsersDataSet(long id, String name) { // this.setId(id); this.setName(name); } |
12
18776 Total Views 5 Views Today
Views: 16 619