有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有共享主键的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) 个答案

  1. # 1 楼答案

    @OneToOne
    @JoinColumn(name = "payment_id")
    @ForeignKey
    private Payment payment;
    

    您可以在此处使用@ForeignKey注释。 编辑

    @OneToOne
    @JoinColumn(name = "payment_id", foreignKey = @ForeignKey(name = "FK_NAME"))
    private Payment payment;