" org.hibernate.TypeMismatchException:提供错误类型的ID"使用@OneToOne进行双向关系时

时间:2017-09-11 16:03:01

标签: java hibernate java-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警告[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:提供了错误类型的id   class com。******。*****。。********。两个。预期:上课   com。******。*****。。********。TwoPK,上课了   com。******。*****。**。********。OnePK at   org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162)     在   org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267)     在

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

  

11:44:35,735警告[org.apache.cxf.phase.PhaseInterceptorChain]   (默认任务-83)拦截器   {http://services.webservices。*****。******。com /} ObjectManagerService#{http://services.webservices。*****。******。com /} getAllObjects   抛出异常,现在展开:org.apache.cxf.interceptor.Fault:   编组错误:在对象图中检测到一个循环。这将   导致无限深的XML:一个[onePK = OnePK [dId = 3151,ldd = 426]] - >   两个[twoPK = OnePK [dId = 3151,ldd = 426]] - >一个[onePK = OnePK [dId = 3151,   ldd = 426]]   org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:266)     在   org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:238)     在   org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:118)     在

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

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

2 个答案:

答案 0 :(得分:0)

我认为问题来自name类中@JoinColumn映射中使用的Two属性,其中name使用的值与referencedColumnName相同{1}}。

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

Entity

注意:

如果您为PK使用两个不同的类,为什么在这两个类中使用相同的属性名称,如果您在@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; OnePk中使用不同的名称标识它们会更好: / p>

分别在TwoPk班级中oneDIdoneLId以及OnePk班级中的twoDIdtwoLId,这将使事情变得更好,更容易阅读,识别和绘图。

答案 1 :(得分:0)

首先,我通过调用this method来增加Oracle UCP中的TTL连接超时,以便摆脱GenericJDBCException。有些请求需要花费太多时间来执行,而允许连接使用的时间太短。

其次,我使用名为OnePK的同一个类作为第一和第二类的主键。

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

第四,我修改了我的管理器,以便他们调用Two.setOne(最后一个),以便为不使用Web服务调用持久层的源代码公开完整的对象(实例为2)。

最后,我修复了一些类似的案例,但是使用@MapsId只有一个列组成的更简单的主键。