带有共享主键的JavaSpring数据JPA:OneToOne似乎不起作用
使用SpringVersion4.0.7中的SpringDataJPA,在Hibernate的支持下(通过导入Envers4.3.6来判断),我希望在两个实体(Payment和PaymentFailure)之间创建一对一的关系
当付款失败时,PaymentFailure将使用付款ID创建。为了做到这一点,我在使用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
缺失,因此以ApplicationContext无法加载而结束:
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一起工作?我现在真的迷路了,我读过很多建议,但都不管用
# 1 楼答案
您可以在此处使用@ForeignKey注释。 编辑