当两个类中的复合主键相同时,我没有成功使用@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对于班级com。******。***** .. ********。两个。预期:上课com。******。***** .. ********。TwoPK,上课com。******。*****。**。 ********。org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162)中的OnePK atg.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267)在
当我使用相同的类(OnePK)作为两个类(一个和两个)的主键时,我得到:
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:一个[onePK = OnePK [dId = 3151,lId = 426]] - >两个[twoPK = OnePK [dId = 3151,ldd = 426]] - >一个[onePK = OnePK [dId = 3151]位于org.apache的org.apache.cxf.jaxB.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:266)org.apache的org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:238)处,lId = 426] .cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:118)at at
使用@PrimaryKeyJoinColumns没有帮助,我使用this answer和this tutorial,我得到了相同的错误消息。使用@MapsId没有帮助,我得到了“org.hibernate.exception.GenericJDBCException:无法准备语句”。也许根本原因是this unfixed bug of Hibernate。我发现的唯一解决方法是删除第一次出现的@OneToOne和“One”类中的字段“two”但是当我删除此实例时,One实例包含的Two实例不再被删除一,这就是我使用CascadeType.ALL的原因。
这个JPA源代码是由Netbeans 8自动生成的。我有点选择。有没有办法让它正常工作?它真的是Hibernate的限制吗?还有另一个JPA正确处理此案例的实现吗?
我认为问题来自name
类中使用的@JoinColumn
属性,在Two
类中,name
的值与referencedColumnName
相同。
实际上Two
类已经有P_ID
类和L_ID
类嵌入了TwoPk
和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;
中所以你应该指定不同的名称:
OnePk
注意:
如果你为PK使用两个不同的类,为什么你在两个类中使用相同的属性名称,如果你用TwoPk
和oneDId
中的不同名称识别它们会更好:
你的oneLId
课程中分别是OnePk
和twoDId
,twoLId
课程中的TwoPk
和this method,这将使事情变得更好,更容易阅读,识别和绘制。
起初,我通过调用GenericJDBCException
来增加Oracle UCP中的TTL连接超时,以便摆脱@XmlTransient
。有些请求花费了太多时间来执行,而允许保持连接使用的时间太短。
其次,我使用名为OnePK的同一个类作为类One和Two的主键。
第三,我在方法getOne()之前将@MapsId
添加到类Two中,以便在XML序列化中修复循环。
第四,我修改了我的管理器,以便他们调用Two.setOne(最后一个),以便为不使用Web服务调用持久层的源代码公开完整的对象(实例为2)。
最后,我修复了一些类似的情况,但是使用qazxswpoi只有一个列组成的更简单的主键。