2017-09-11 1 views
0

Es ist mir nicht möglich, @OneToOne zu verwenden, wenn der zusammengesetzte Primärschlüssel in beiden Klassen identisch ist:"org.hibernate.TypeMismatchException: Bereitgestellte ID des falschen Typs" bei Verwendung von @OneToOne für eine bidirektionale Beziehung

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

Wenn ich den Quellcode verwenden oben, wie ist, erhalte ich:

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

Wenn ich die gleiche Klasse (OnePK) als Primärschlüssel für beide Klassen verwenden (eins und zwei), erhalte ich:

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

Die Verwendung von @PrimaryKeyJoinColumns hat nicht geholfen, ich habe this answer und this tutorial verwendet, ich habe die gleichen Fehlermeldungen. Using @MapsId hat nicht geholfen, ich habe "org.hibernate.exception.GenericJDBCException: konnte Anweisung nicht vorbereiten". Vielleicht ist die Ursache this unfixed bug of Hibernate. Die einzige Problemumgehung, die ich gefunden habe, besteht darin, das allererste Vorkommen von @OneToOne und das Feld "two" in der Klasse "One" zu entfernen, aber die durch eine Instanz von One enthaltene Instanz von Two wird nicht mehr gelöscht, wenn ich diese Instanz lösche von One, deshalb habe ich CascadeType.ALL benutzt.

Dieser JPA-Quellcode wird automatisch von Netbeans 8 generiert. Ich bin ein wenig außerhalb der Optionen. Gibt es eine Möglichkeit, es richtig funktionieren zu lassen? Ist es wirklich eine Einschränkung von Hibernate? Gibt es eine andere Implementierung von JPA, die diesen Fall korrekt behandelt?

Antwort

0

Zuerst erhöhte ich die Zeitüberschreitung der TTL-Verbindung in Oracle UCP durch Aufruf von this method, um die GenericJDBCException loszuwerden. Einige Anfragen benötigten zu viel Zeit, um ausgeführt zu werden, während die Zeit, die zum Aufrechterhalten einer Verbindung verwendet wurde, zu niedrig war.

Zweitens verwendete ich die gleiche Klasse namens OnePK als Primärschlüssel der beiden Klassen eins und zwei.

Drittens, ich habe @XmlTransient in die Klasse Zwei vor der Methode getOne() hinzugefügt, um den Zyklus in der XML-Serialisierung zu beheben.

Viertens habe ich meine Manager so geändert, dass sie Two.setOne (final One one) aufrufen, um vollständige Objekte (Instanzen von Two) für den Quelltext verfügbar zu machen, der die Persistenzebene aufruft, ohne die Webdienste zu verwenden.

Endlich habe ich einige ähnliche Fälle behoben, aber mit einfacheren Primärschlüsseln, die nur aus einer Spalte bestanden, indem @MapsId verwendet wurde.

0

ich glaube, das Problem aus der in Ihrem @JoinColumn Mapping verwendet name Attribut kommt, in Ihrer Two Klasse, wo die für name verwendet Wert der gleiche wie referencedColumnName ist.

In der Tat Two Klasse hat bereits P_ID und L_ID Attribute aus seiner TwoPk Klasse eingebettet, so dass, wenn Sie die gleichen Namen verwenden name = "P_ID" und name = "L_ID", können Sie nicht beide Klasse Karte, da diese Attribute bereits in diesem Entity sind so sollten Sie spezifizieren verschiedene Namen:

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

Hinweis:

Wenn Sie zwei differents Klassen für PKs verwenden Warum verwenden Sie die gleichen Attribute Namen in beiden Klassen, es wäre besser, wenn man sie mit differents Namen in OnePk und TwoPk als identifiziert:

Beziehungsweise oneDId und oneLId in Ihrer OnePk Klasse und twoDId und twoLId in Ihrer TwoPk Klasse, Das macht die Dinge besser und einfacher zu lesen, zu identifizieren und zu kartieren.

+0

Ok, ich werde es versuchen. Vielen Dank. – gouessej

+0

Eigentlich kann ich diese Namen im Java-Quellcode nicht ändern, da ich sie nicht in den SQL-Tabellen ändern darf, sie müssen übereinstimmen: s – gouessej

+0

Nun, Sie können ihnen verschiedene Namen in Java geben und denselben Namen verwenden die '@ Column'-Annotation, aber das ist hier nicht der Punkt, hat die '@ JoinColumns'-Konfiguration geändert? –

Verwandte Themen