Issues with inheritance
donniedarko Sep 27, 2005 1:32 PMI have encountered issues with entity enheritance. Here is my case:
I basically followed the instructions in the tutorial when i coded.
First I have a base entity class called Message like this:
package ejb3.language.system; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE, discriminatorType = DiscriminatorType.STRING) @DiscriminatorColumn(name = "TYPE", columnDefinition="VARCHAR(255)", nullable = true) public class Message implements Serializable { private static final long serialVersionUID = 1L; private MessagePK pk; private String value; @EmbeddedId public MessagePK getPk() { return pk; } public void setPk(MessagePK pk) { this.pk = pk; } @Column(columnDefinition="text") public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
This entity bean has a composite primary key class like this:
package ejb3.language.system; import java.io.Serializable; import javax.persistence.AccessType; import javax.persistence.Embeddable; @Embeddable(access = AccessType.PROPERTY) public class MessagePK implements Serializable { private static final long serialVersionUID = 1L; private String object_member; private int object_id; private String url; public int getObject_id() { return object_id; } public void setObject_id(int object_id) { this.object_id = object_id; } public String getObject_member() { return object_member; } public void setObject_member(String object_member) { this.object_member = object_member; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
I then have some classes that inherits from the base class in order to achieve different "types" to be stored within the same table. Like this one:
package ejb3.language.system; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import com.lightminds.ppdb.ejb3.country.Country; @Table(name="Message") @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE, discriminatorType = DiscriminatorType.STRING, discriminatorValue = "Country") public class Message_CountryView extends Message implements Serializable { private static final long serialVersionUID = 1L; private Country country; @ManyToOne @JoinColumn(name = "object_id", insertable=false, updatable=false) public Country getCountry() { return country; } public void setCountry(Country country) { this.country = country; } }
All fine. And all deployes well on latest RC2 release of EJB3. I can successfully add both Messages and Country and other into the table with the normal persist stuff. However when I try to fetch a specific row in the database represented by one of the inherited clasess I get errors.
First If I try something like this:
MessagePK pk = new MessagePK(); pk.setObject_id(1); pk.setObject_member("test2"); pk.setUrl("www.mysite.org"); Message_CountryView message = MyEntityManager.find(Message_CountryView.class, pk);
I get the following error:
org.hibernate.exception.GenericJDBCException: could not load an entity: [ejb3.language.system.Message_CountryView#component[url,object_id,object_member]{object_id=1, url=www.mysite.org, object_member=test2}]
.......
Caused by: java.sql.SQLException: Invalid value for getInt() - 'test2' in column 3
and if I manually create a query like this:
Message_CountryView message = (Message_CountryView)MyEntityManager.createQuery("SELECT mcv FROM Message_CountryView mcv WHERE mcv.pk = :key").setParameter("key", pk).getSingleResult();
I get a similar error:
org.hibernate.exception.DataException: could not execute query
.........
Caused by: java.sql.SQLException: Operand should contain 3 column(s)
Also note that if I create an entry with the type of the base class. I.e Message - both the above "finds" works if the row returned is of the base class type, but If I query for an entry that is represented by one of the inherited classes I get the above errors even if I query for the base class (Message message = MyEntityManager.find(Message.class, pk);)
Thanks in advance