java - 使用 @OneToOne 进行双向关系时为 "org.hibernate.TypeMismatchException: Provided id of the wrong type"

标签 java hibernate jakarta-ee jpa-2.0 type-mismatch

当两个类中的复合主键相同时,我无法成功使用 @OneToOne:

@Entity
public class One implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    private OnePK onePK;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "one")
    private Two two;
    //... constructors, getters and setters
}

@Entity
public class Two implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    private TwoPK twoPK;
    @JoinColumns({
        @JoinColumn(name = "P_ID", referencedColumnName = "P_ID", insertable = false, updatable = false),
        @JoinColumn(name = "L_ID", referencedColumnName = "L_ID", insertable = false, updatable = false)})
    @OneToOne(optional = false)
    private One one;
    //... constructors, getters and setters
}

@Embeddable
public class OnePK implements Serializable {
    @Basic(optional = false)
    @Column(name = "P_ID")
    private BigInteger dId;
    @Basic(optional = false)
    @Column(name = "L_ID")
    private BigInteger lId;
    //... constructors, getters and setters
}

@Embeddable
public class TwoPK implements Serializable {
    @Basic(optional = false)
    @Column(name = "P_ID")
    private BigInteger dId;
    @Basic(optional = false)
    @Column(name = "L_ID")
    private BigInteger lId;
    //... constructors, getters and setters
}

当我按原样使用上面的源代码时,我得到:

12:56:04,021 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-83) Application {http://services.webservices.*****.******.com/}ObjectManagerService#{http://services.webservices.*****.******.com/}getAllObjects has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: java.lang.IllegalArgumentException: org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.******.*****..********.Two. Expected: class com.******.*****..********.TwoPK, got class com.******.*****.**.********.OnePK at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162) at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267) at

当我使用相同的类 (OnePK) 作为两个类(一和二)的主键时,我得到:

11:44:35,735 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-83) Interceptor for {http://services.webservices.*****.******.com/}ObjectManagerService#{http://services.webservices.*****.******.com/}getAllObjects has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Marshalling Error: A cycle is detected in the object graph. This will cause infinitely deep XML : One[ onePK=OnePK[ dId=3151, lId=426 ] ] -> Two[ twoPK=OnePK[ dId=3151, lId=426 ] ] -> One[ onePK=OnePK[ dId=3151, lId=426 ] ] at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:266) at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:238) at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:118) at

使用@PrimaryKeyJoinColumns没有帮助,我使用了this answerthis tutorial ,我收到了相同的错误消息。使用 @MapsId 没有帮助,我得到“org.hibernate.exception.GenericJDBCException:无法准备语句”。也许根本原因是 this unfixed bug of Hibernate 。我发现的唯一解决方法是删除“One”类中第一次出现的 @OneToOne 和字段“two”,但是当我删除 One 的此实例时,One 的实例包含的 Two 的实例不再被删除,这就是我使用 CascadeType.ALL 的原因。

这个 JPA 源代码是由 Netbeans 8 自动生成的。我有点没有选择。有没有办法让它正常工作?这真的是 Hibernate 的限制吗? JPA 是否有另一种实现可以正确处理这种情况?

最佳答案

我认为问题出在 Two 类的 @JoinColumn 映射中使用的 name 属性,其中 name 使用的值与 referencedColumnName 相同。

事实上,Two 类已经从其 TwoPk 类中嵌入了 P_IDL_ID 属性,因此当您使用相同的名称 name = "P_ID"name = "L_ID" 时,您无法映射这两个类,因为这些属性已经在此 Entity 中,因此您应该指定不同的名称:

@JoinColumns({
    @JoinColumn(name = "OneP_ID", referencedColumnName = "P_ID", insertable = false, updatable = false),
    @JoinColumn(name = "OneL_ID", referencedColumnName = "L_ID", insertable = false, updatable = false)})
@OneToOne(optional = false)
private One one;

注意:

如果您使用两个不同的类进行 PK,为什么在两个类中使用相同的属性名称,最好在 OnePkTwoPk 中使用不同的名称来标识它们,如下所示:

分别在 OnePk 类中使用 oneDIdoneLId,在 TwoPk 类中使用 twoDIdtwoLId,这将使内容变得更好、更容易阅读、识别和映射。

关于java - 使用 @OneToOne 进行双向关系时为 "org.hibernate.TypeMismatchException: Provided id of the wrong type",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46159867/

相关文章:

Android 应用程序上的 Java 套接字异常,需要帮助吗?

java - 适配器的内容已更改,但 ListView 未收到通知。内容适配器未从后台线程修改

mysql - 将 SQL 查询转换为 Hibernate 查询

java - JPA 中外键的主详细信息 ID

Windows Server 2012 上的 JavaService.exe

hibernate - 在 Tomcat 服务器中部署的 2 个 J2EE 应用程序之间共享 jsp session

hibernate - 使用 Tomcat 6.0 作为 java web 应用程序的服务器导致 javax.persistence 注释被搞乱

soap - 迁移到 Jakarta : ClassNotFoundException: com. sun.xml.internal.ws.spi.ProviderImpl

java - 简单日期格式java模式

java - 使用Spring框架是否可以根据某些业务逻辑连接两个不同的数据库