-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: OneToOne composite key und org.hibernate.TypeMismatchEx
PostPosted: Mon Jan 19, 2009 8:07 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
Hallo,

ich hab ein Problem...

I bekomm diese fehlermeldung:
Code:
org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: myEntities.Product$ProductID, got class myEntities.Item$ItemID
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)


Die ProductID in der Tabelle Produkt ist ein zusammengesetzter Schlüssel. Die Tabelle Item hat auch einen zusammengesetzten Schlüssel und hat die selben Spalten als zusammengesetzten Schlüssel wie in Tabelle Produkt:


Code:
public class Product implements Serializable {
   
public static class ProductID implements Serializable
{
@Column(name = "ID_A", nullable = false, columnDefinition = "integer")
private Integer idA;

@Column(name = "ID_B", nullable = false, columnDefinition = "integer")
private Integer idB;
}

@EmbeddedId
private ProductID productID = new DocumentID();
getter/setter


@OneToOne(fetch = FetchType.EAGER, optional = true)
@JoinColumns({
@JoinColumn(name="ID_A", referencedColumnName="ID_A", nullable = false, insertable = false, updatable = false),   
       @JoinColumn(name="ID_B", referencedColumnName="ID_B", nullable = false, insertable = false, updatable = false) })
private Item item;
//getter/setter

}



Code:
public class Item implements Serializable {
   
public static class ItemID implements Serializable
{
@Column(name = "ID_A", nullable = false, columnDefinition = "integer")
private Integer idA;

@Column(name = "ID_B", nullable = false, columnDefinition = "integer")
private Integer idB;
}

@EmbeddedId
private ItemID itemID = new ItemID();
getter/setter


@OneToOne(fetch = FetchType.EAGER, optional = true, mappedBy="item")
private Product product;
//getter/setter


}


Diese HQL funzt und gibt mir alle Item-Instanzen eines Produkts zurück:

Code:
select a.item from Product a


Aber dieses HQL funzt NICHT:

Code:
select a from Product a


und gibt mir diese Fehlermeldung:
Code:
org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: myEntities.Product$ProductID, got class myEntities.Item$ItemID
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)


(Noch was anderes: Wenn ich die @OneToOne über den getter statt über dem Feld deklariere, ignoriert Hibernate mein OneToOne-Mapping und nimmt die Item-Instanz fälschlicherweise als Spalte wahr.)


Kennt sich da einer aus, wie man sowas am besten macht?

(Mit @PrimaryKeyJoinColumns kommt die selbe fehlermeldung, und SecondaryTable ist hier nicht sinnvoll).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 8:23 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
Zu dem einem Problem:
Quote:
Wenn ich die @OneToOne über den getter statt über dem Feld deklariere, ignoriert Hibernate mein OneToOne-Mapping und nimmt die Item-Instanz fälschlicherweise als Spalte wahr.


Mapping-Annotationen kannst du entweder über den Attributen oder über den Gettern platzieren. Hibernate richtet sich danach, wo die Id-Annotation, oder in deinem Fall die EmbeddedId, steht und liest die Annotationen dann auf die gleiche Weise. Mischen geht also nicht. Zu empfehlen sind die Annotationen über den gettern, da dies Hibernate-Standardvorgehen (und in seltenen Fällen auch performanter) ist.

Kannst du für den Hauptproblem den Code posten, in dem du die HQLs ausführst?

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 8:45 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
hallo mmerder,

danke zu dem Problem:

Quote:
Wenn ich die @OneToOne über den getter statt über dem Feld deklariere, ignoriert Hibernate mein OneToOne-Mapping und nimmt die Item-Instanz fälschlicherweise als Spalte wahr.


Hier der überarbeitete Code(nun funzt die Relation über den Getter):

Code:
public class Product implements Serializable {
   
public static class ProductID implements Serializable
{

private Integer idA;
@Column(name = "ID_A", nullable = false, columnDefinition = "integer")
getter/setter

private Integer idB;
@Column(name = "ID_A", nullable = false, columnDefinition = "integer")
getter/setter
}

private ProductID productID;
@EmbeddedId
getter/setter

private Item item;

@OneToOne(fetch = FetchType.EAGER, optional = true)
@JoinColumns({
@JoinColumn(name="ID_A", referencedColumnName="ID_A", nullable = false, insertable = false, updatable = false),   
       @JoinColumn(name="ID_B", referencedColumnName="ID_B", nullable = false, insertable = false, updatable = false) })
//getter/setter

}




Zum Hauptproblem:

Ich nutze einfach die Hibernate-Console um mir die Resultate einer Abfrage anzeigen zu können:

"select a from Product a"

generiert zwar die richtige SQL, aber bringt mir keine Resultate zurück, sondern nur diese Exception:

Code:
org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: myEntities.Product$ProductID, got class myEntities.Item$ItemID
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)



Die selbe Fehlermeldung erscheint aber auch in meinem Log-File, wenn ich diese Query mach:

Code:
entityManager.createQuery("from Product a")


wenn ich z.B. zur relation Item navigiere, geht es (gib mir die Item-Instanz der Produkt-Instanz zurück):
Code:
select a.item from Product a


wenn ich z.B. geziehlt felder selektier, geht es auch:

Code:
select a.name from Product a


Meine Mapping ist anscheinend falsch, die CompositeKey einer Entität entspricht ja den Wert der CompositeKey der anderen Entität.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 8:53 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
Ich glaube, ich verstehe dein Problem. Du hast eine OneToOne-Beziehung. Eine solche Beziehung wird meist so abgebildet, dass der Primärschlüssel auch der Fremdschlüssel ist. Daher erwartet Hibernate hierbei, dass beide Klassen die gleiche Art von Primärschlüssel haben. Nimm die gleiche Id-Klasse für beide Klassen, dann sollte es funktionieren und du hast Code gespart. ;-)

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:21 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
oh jaaa:

also so:

Code:
public class Item implements Serializable {
 
// wird nicht mehr benötigt:
//public static class ItemID implements Serializable


// ProductID statt ItemID
@EmbeddedId
private ProductID itemID;
getter/setter


@OneToOne(fetch = FetchType.EAGER, optional = true, mappedBy="item")
private Product product;
//getter/setter


}


nun funzt das mit der abfrage, aber noch ne frage:

Wäre es nicht besser (sauberer?), in der Tabelle die "ItemID" zu lassen und folgendes zu machen:

Code:
@EmbeddedId
@GenericGenerator(name = "SharedPrimKey", strategy = "foreign", parameters = { @org.hibernate.annotations.Parameter(name = "property", value = "product") })
@GeneratedValue(generator = "SharedKey")
private ItemID itemID;
getter/setter


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:29 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
hmm, ich finde es nicht soo schön, da es sehr kompliziert ist für ein einfaches Problem.

Am besten, du nennst deine Klasse ProductID um, in etwas abstrakteres, falls du sie noch öfter benutzt und machst daraus ne "Toplevel"-Klasse, also keine innere Klasse von Produkt mehr.

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:33 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
.doublePost


Last edited by nimo23 on Mon Jan 19, 2009 10:51 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 9:35 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
doublePost


Last edited by nimo23 on Mon Jan 19, 2009 10:51 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 10:38 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
ja, da hast du recht..zu Kollisionen der statischen Klasse kann es ja (hoffe ich) nicht kommen, da ich hashCode/equals in jeder Klasse überschreibe:-)

DANKE!!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.