创建三个实体时出现分离实体传递到持久化错误



我有三个实体CustomerDetailsAddressLineBankdetails。当我试图使用CrudRepository在h2db中创建条目时,它会抛出一个错误,将其中一个声明为分离实体。有人能告诉我为什么会出现这个错误吗?

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.ABC.AAP.Domain.Address
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:120) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:745) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:713) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:298) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:492) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:416) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:427) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:721) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:707) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at com.sun.proxy.$Proxy77.persist(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:554) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
... 21 common frames omitted

此错误是在创建实体时抛出的。org.hibernate.PersistentObjectException:传递给持久化的分离实体:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class BankDetails {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private long id;

private String bank_name;
private String account_number;
private String ifsc_code;
private String party_account_type;


@OneToOne(mappedBy = "bank_details") private CustomerDetails
customer_details;



@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BankDetails other = (BankDetails) obj;
if (id != other.id)
return false;
return true;
}
public BankDetails(String bank_name, String account_number, String ifsc_code, String party_account_type) {
super();
this.bank_name = bank_name;
this.account_number = account_number;
this.ifsc_code = ifsc_code;
this.party_account_type = party_account_type;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getBank_name() {
return bank_name;
}
public void setBank_name(String bank_name) {
this.bank_name = bank_name;
}
public String getAccount_number() {
return account_number;
}
public void setAccount_number(String account_number) {
this.account_number = account_number;
}
public String getIfsc_code() {
return ifsc_code;
}
public void setIfsc_code(String ifsc_code) {
this.ifsc_code = ifsc_code;
}
public String getParty_account_type() {
return party_account_type;
}
public void setParty_account_type(String party_account_type) {
this.party_account_type = party_account_type;
}
}
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class CustomerDetails {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;


private String party_code;
private String title;
private String first_name;
private String last_name;
private String sex;
private String nationality;


@OneToOne(cascade = CascadeType.ALL)

@JoinColumn(name="address_id",referencedColumnName = "id") private Address
addressline;


private String mobile_number;
private String email_id;
private String party_occupation;
private String pan_number;
private String tan_number;
private Date date_of_birth;
private String business_type;

@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="bank_details_id",referencedColumnName = "id")
private BankDetails bank_details;

public CustomerDetails(String party_code, String title, String first_name, String last_name, String sex,
String nationality, Address addressline, String mobile_number, String email_id, String party_occupation,
String pan_number, String tan_number, Date date_of_birth, String business_type, BankDetails bank_details) {
super();
this.party_code = party_code;
this.title = title;
this.first_name = first_name;
this.last_name = last_name;
this.sex = sex;
this.nationality = nationality;
this.addressline = addressline;
this.mobile_number = mobile_number;
this.email_id = email_id;
this.party_occupation = party_occupation;
this.pan_number = pan_number;
this.tan_number = tan_number;
this.date_of_birth = date_of_birth;
this.business_type = business_type;
this.bank_details = bank_details;
}



@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}



@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CustomerDetails other = (CustomerDetails) obj;
if (id != other.id)
return false;
return true;
}



public String getParty_code() {
return party_code;
}

public void setParty_code(String party_code) {
this.party_code = party_code;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getFirst_name() {
return first_name;
}

public void setFirst_name(String first_name) {
this.first_name = first_name;
}

public String getLast_name() {
return last_name;
}

public void setLast_name(String last_name) {
this.last_name = last_name;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getNationality() {
return nationality;
}

public void setNationality(String nationality) {
this.nationality = nationality;
}

/*
* public Address getAddressline() { return addressline; }
* 
* public void setAddressline(Address addressline) { this.addressline =
* addressline; }
*/


public String getMobile_number() {
return mobile_number;
}

public void setMobile_number(String mobile_number) {
this.mobile_number = mobile_number;
}

public String getEmail_id() {
return email_id;
}

public void setEmail_id(String email_id) {
this.email_id = email_id;
}

public String getParty_occupation() {
return party_occupation;
}

public void setParty_occupation(String party_occupation) {
this.party_occupation = party_occupation;
}

public String getPan_number() {
return pan_number;
}

public void setPan_number(String pan_number) {
this.pan_number = pan_number;
}

public String getTan_number() {
return tan_number;
}

public void setTan_number(String tan_number) {
this.tan_number = tan_number;
}

public Date getDate_of_birth() {
return date_of_birth;
}

public void setDate_of_birth(Date date_of_birth) {
this.date_of_birth = date_of_birth;
}

public String getBusiness_type() {
return business_type;
}

public void setBusiness_type(String business_type) {
this.business_type = business_type;
}

public BankDetails getBank_details() {
return bank_details;
}

public void setBank_details(BankDetails bank_details) {
this.bank_details = bank_details;
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;


@OneToOne(mappedBy = "addressline") private CustomerDetails customer_details;


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (id != other.id)
return false;
return true;
}
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String pincode;



public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Address(String address1, String address2, String city, String state, String country, String pincode) {
super();
this.address1 = address1;
this.address2 = address2;
this.city = city;
this.state = state;
this.country = country;
this.pincode = pincode;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
}

**问题已解决:问题是由于创建条目期间的级联类型造成的我使用的是CascadeType.ALL,但当更改为CascadeType.MERGE时,它被解决了

我认为问题出在实体中,如果你是自己添加ID,hibernate会认为这个实体已经在DB中了,对他来说它是分离的实体。

提示:尽量不要使用GenerationType.AUTO,而是使用SEQUENCE或IDENTITY作为更好的方法。

AUTO-我们将ID创建策略委托给持久性提供者,这并不总是最好的方法。

https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/GenerationType.html更多关于策略的信息。

最新更新