使用Spring版本4.0.7中的Spring Data JPA,由Hibernate支持(通过导入Envers 4.3.6判断),我想在两个实体之间建立一对一的关系 - Payment和PaymentFailure。
付款失败时,会创建一个ID为Payment的PaymentFailure。尝试这样做时,我在使用StackOverflow和其他地方的任何推荐代码片段时会遇到各种错误。
例如,在使用@Id
和@MapsId
时,我遇到了DataIntegrityViolationException
:
org.springframework.web.util.NestedServletException: Request processing failed;
nested exception is org.springframework.dao.DataIntegrityViolationException:
A different object with the same identifier value was already associated
with the session : [blah.payment.PaymentFailure#172656];
nested exception is javax.persistence.EntityExistsException:
A different object with the same identifier value was already associated
with the session : [blah.payment.PaymentFailure#172656]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:141)
付款实体看起来像是:
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;
import javax.persistence.*;
import java.io.Serializable;
@Audited
@Entity
@Table(name = "payment")
@DynamicInsert
public class Payment implements Serializable {
@Id
@GeneratedValue
private Long id;
@NotAudited
@OneToOne(mappedBy = "payment", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private PaymentFailure paymentFailure;
// ... other fields, setters ...
}
这是PaymentFailure:
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "payment_failure")
public class PaymentFailure implements Serializable {
@Id
private Long id;
@MapsId
@OneToOne
@JoinColumn(name = "payment_id")
private Payment payment;
// ... getters, setters, other fields
}
我也尝试修改它,有人推荐在Hibernate JPA指南中提到的更好的版本,你没有单独的ID字段:
@Id
@OneToOne
@JoinColumn(name = "payment_id")
private Payment payment;
然而,由于IllegalArgumentException
表示缺少注释@IdClass
,因此无法加载,因此无法加载;但
Caused by: java.lang.IllegalArgumentException:
This class [class blah.payment.PaymentFailure] does not define an IdClass
at org.hibernate.jpa.internal.metamodel
.AbstractIdentifiableType.getIdClassAttributes(AbstractIdentifiableType.java:200)
at org.springframework.data.jpa.repository.support
.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:221)
at org.springframework.data.jpa.repository.support
.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:79)
at org.springframework.data.jpa.repository.support
.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
at org.springframework.data.jpa.repository.support
.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:149)
at org.springframework.data.jpa.repository.support
.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:88)
at org.springframework.data.jpa.repository.support
.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:68)
at org.springframework.data.repository.core.support
.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158)
at org.springframework.data.repository.core.support
.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
at org.springframework.data.repository.core.support
.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
at org.springframework.data.jpa.repository.support
.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support
.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
at org.springframework.beans.factory.support
.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
是否有一些方法可以在我的设置中使用?或者,它可能适用于更高版本的Spring或Hibernate吗?我现在真的输了,我已经阅读了很多建议,但都没有。
答案 0 :(得分:-1)
@OneToOne
@JoinColumn(name = "payment_id")
@ForeignKey
private Payment payment;
您可以在此处使用@ForeignKey注释。 编辑 -
@OneToOne
@JoinColumn(name = "payment_id", foreignKey = @ForeignKey(name = "FK_NAME"))
private Payment payment;