JPA/Hibernate报错:detached entity passed to persist问题求助
Hey there! Let's break down why you're getting that org.hibernate.PersistentObjectException: detached entity passed to persist: model.Employee error and fix it up.
What's causing this error?
The core issue here is how JPA/Hibernate handles entity states, paired with your Employee entity setup:
- Your
eidfield uses@GeneratedValue(strategy = GenerationType.AUTO), which tells Hibernate to automatically generate the primary key value for new entities. You don't need to set this manually. - The
persist()method is only meant for transient entities—brand new objects that don't have a primary key value yet. If you set theeidyourself (either via the constructor with aneidparameter orsetEid()), Hibernate sees this entity as detached (like it was already persisted before and is now outside the EntityManager's control) and throws this error becausepersist()can't handle detached entities.
Looking at your code, it's likely you were setting the eid value in your incomplete CreateEmployee class, which triggered this problem.
How to fix it
Here are the straightforward solutions tailored to your setup:
Let Hibernate handle the primary key (recommended)
Since you're using@GeneratedValue, stop manually setting theeidentirely. Use the no-arg constructor and skip callingsetEid(). Here's what your correctedCreateEmployeecode would look like:package service; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import model.Employee; public class CreateEmployee { public static void main( String[ ] args ) { EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "sample" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); // Use the no-arg constructor, don't set eid Employee employee = new Employee(); employee.setEname("Alice Smith"); employee.setSalary(6500.0); employee.setDeg("Software Engineer"); entitymanager.persist(employee); // This will work now entitymanager.getTransaction( ).commit( ); // Don't forget to close resources! entitymanager.close(); emfactory.close(); } }You can also optionally modify your
Employeeclass to remove the constructor that takeseid—this will prevent accidental manual key assignment in the future.If you must set the primary key manually (not recommended for auto-generated keys)
If you have a specific reason to seteidyourself, replacepersist()withmerge().merge()works with detached entities and will either update an existing record or insert a new one if the key doesn't exist:Employee employee = new Employee(1, "Bob Brown", 7000.0, "Senior Developer"); entitymanager.merge(employee); // Use merge instead of persistNote: This defeats the purpose of using
@GeneratedValue, so only do this if you have a clear need.Bonus: Add auto-table creation to your persistence.xml
As a JPA beginner, adding this property to yourpersistence.xmlwill let Hibernate automatically create/update your database tables, saving you manual setup work:<properties> <!-- Your existing DB properties --> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties>
Quick recap
This error happens because you tried to use persist() on an entity that already had a primary key value (which Hibernate interpreted as detached). The simplest fix is to let Hibernate generate the key for you by not setting eid manually.
内容的提问来源于stack exchange,提问作者Harvey

