“org.hibernate.TypeMismatchException:提供的错误类型的ID”当使用@OneToOne作为双向关系时 [英] "org.hibernate.TypeMismatchException: Provided id of the wrong type" when using @OneToOne for a bi-directional relation

查看:430
本文介绍了“org.hibernate.TypeMismatchException:提供的错误类型的ID”当使用@OneToOne作为双向关系时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  @Entity 
public class One实现Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
私人OnePK onePK;
@OneToOne(cascade = CascadeType.ALL,mappedBy =one)
private two two;
// ...构造函数,getter和setter
}

@实体
public class Two实现Serializable {
private static final long serialVersionUID = 1L ;
@EmbeddedId
私人TwoPK twoPK;
@JoinColumn({
@JoinColumn(name =P_ID,referencedColumnName =P_ID,insertable = false,updatable = false),
@JoinColumn(name =L_ID,referencedColumnName =L_ID,insertable = false,updatable = false)})
@OneToOne(可选项= false)
private one one;
// ...构造函数,getters和setters
}

@Embeddable
公共类OnePK实现Serializable {
@Basic(可选= false)
@Column(name =P_ID)
私人BigInteger dId;
@Basic(可选= false)
@Column(name =L_ID)
私人BigInteger lId;
// ...构造函数,getters和setters
}

@Embeddable
public class TwoPK实现Serializable {
@Basic(可选= false)
@Column(name =P_ID)
私人BigInteger dId;
@Basic(可选= false)
@Column(name =L_ID)
私人BigInteger lId;
// ...构造函数,getters和setters
}

使用上面的源代码,我得到:

lockquote
12:56:04,021警告[org.apache.cxf.phase.PhaseInterceptorChain]
(默认任务-83)应用程序
{ http://services.webservices 。** ***。******。com /} ObjectManagerService#{ http://services.webservices 。* ****。******。com /} getAllObjects
引发异常,现在展开:org.apache.cxf.interceptor.Fault:
java.lang.IllegalArgumentException:
org.hibernate.TypeMismatchException:为
class com。******。*****。。********。提供了错误类型的id。预计:班级
com。******。*****。
。********。TwoPK,班级
com。**** **。*****。**。********。OnePK at
org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162)

org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267)
at



<当我使用相同的类(OnePK)作为这两个类的主键(One和Two)时,我得到:


11 :44:35,735 WARNING [org.apache.cxf.phase.PhaseInterceptorChain]
(默认任务83)
的拦截器{ http://services.webservices 。*****。******。com /} ObjectManagerService#{ http://services.webservices 。*****。******。com /} getAllObjects
引发异常,现在展开:org.apache.cxf。 interceptor.Fault:
编组错误:一个循环在对象图中被检测到。这将
导致无限深的XML:One [onePK = OnePK [dId = 3151,lId = 426]] - >
两个[twoPK = OnePK [dId = 3151,lId = 426]] - > One
中的[onePK = OnePK [dId = 3151,
lId = 426]] 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)

使用@PrimaryKeyJoinColumns没有帮助,我使用这个答案本教程,我收到了相同的错误消息。使用@MapsId没有帮助,我得到了org.hibernate.exception.GenericJDBCException:无法准备语句。也许根本原因是这个未修复的Hibernate错误。我找到的唯一解决方法是删除第一次出现的@OneToOne和类One中的字段two,但是当删除此实例时,包含在One的实例中的实例不再被删除One,这就是我使用CascadeType.ALL的原因。



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

解决方案

首先,我通过调用Oracle UCP中的TTL连接超时此方法为了摆脱 GenericJDBCException 。一些请求花费了太多时间来执行,而允许使用连接的时间太短。其次,我使用同一个名为OnePK的类作为主要



第三,在方法getOne之前,我将 @XmlTransient 添加到类Two中()以修复循环的XML序列化。

第四,我修改了我的管理器,以便他们调用Two.setOne(final One one)以便公开完整的对象(两个实例),用于调用持久层而不使用Web服务的源代码。



最后,我修复了一些类似的情况,只有一列的使用 @MapsId


I don't succeed in using @OneToOne when the composite primary key is the same in both classes:

@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
}

When I use the source code above as is, I get:

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

When I use the same class (OnePK) as the primary key of both classes (One and Two), I get:

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

Using @PrimaryKeyJoinColumns didn't help, I used this answer and this tutorial, I got the same error messages. Using @MapsId didn't help, I got "org.hibernate.exception.GenericJDBCException: could not prepare statement". Maybe the root cause is this unfixed bug of Hibernate. The only workaround that I've found consists in removing the very first occurrence of @OneToOne and the field "two" in the class "One" but the instance of Two contained by an instance of One no longer gets deleted when I delete this instance of One, that's why I used CascadeType.ALL.

This JPA source code is auto-generated by Netbeans 8. I'm a bit out of options. Is there a way of making it work correctly? Is it really a limitation of Hibernate? Is there another implementation of JPA handling this case correctly?

解决方案

At first, I increased the TTL connection timeout in Oracle UCP by calling this method in order to get rid of the GenericJDBCException. Some requests were taking too much time to execute whereas the time allowed to keep a connection in use was too low.

Secondly, I used the same class named OnePK as the primary key of both classes One and Two.

Thirdly, I added @XmlTransient into the class Two before the method getOne() in order to fix the cycle in the XML serialization.

Fourthly, I modified my managers so that they call Two.setOne(final One one) in order to expose complete objects (instances of Two) for the source code calling the persistence layer without using the web services.

At last, I fixed some similar cases but with simpler primary keys composed of only one column by using @MapsId.

这篇关于“org.hibernate.TypeMismatchException:提供的错误类型的ID”当使用@OneToOne作为双向关系时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆