当两个类中的复合主键相同时,我没有成功使用@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 answer和this tutorial,我得到了相同的错误消息。使用@MapsId没有帮助,我得到了#org.hibernate.exception.GenericJDBCException:无法准备语句"。也许根本原因是this unfixed bug of Hibernate。我发现的唯一解决方法是删除第一次出现的@OneToOne和字段"两个"在班上" One"但是当我删除One的实例时,One实例包含的Two实例不再被删除,这就是我使用CascadeType.ALL的原因。
此JPA源代码由Netbeans 8自动生成。我有点选择。有没有办法让它正常工作?它真的是Hibernate的限制吗? JPA是否有另一种正确处理此案例的实现?
答案 0 :(得分:0)
我认为问题来自name
类中@JoinColumn
映射中使用的Two
属性,其中name
使用的值与referencedColumnName
相同{1}}。
事实上,Two
类已经从其P_ID
类中嵌入了L_ID
和TwoPk
个属性,因此当您使用相同的名称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
班级中oneDId
和oneLId
以及OnePk
班级中的twoDId
和twoLId
,这将使事情变得更好,更容易阅读,识别和绘图。
答案 1 :(得分:0)
首先,我通过调用this method来增加Oracle UCP中的TTL连接超时,以便摆脱GenericJDBCException
。有些请求需要花费太多时间来执行,而允许连接使用的时间太短。
其次,我使用名为OnePK的同一个类作为第一和第二类的主键。
第三,我在方法getOne()之前将@XmlTransient
添加到类Two中,以便在XML序列化中修复循环。
第四,我修改了我的管理器,以便他们调用Two.setOne(最后一个),以便为不使用Web服务调用持久层的源代码公开完整的对象(实例为2)。
最后,我修复了一些类似的案例,但是使用@MapsId
只有一个列组成的更简单的主键。