-->
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.  [ 8 posts ] 
Author Message
 Post subject: Polymorphic associations with annotations
PostPosted: Thu Sep 27, 2007 8:25 am 
Newbie

Joined: Thu Sep 27, 2007 1:15 am
Posts: 3
Location: Amsterdam
Hi all,

We're encountering some problems with polymorphic associations.

First of all where using hibernate version 3.2.1.

Overview of domain model (simplified version)

Code:
       -----------------------            -----------------------                 
       |                     |*          *|                     |                 
       |    PointOfSaleDo    |----------->|  AbstractLocationDo |                 
       |                     |            |                     |                 
       -----------------------            -----------------------                 
                                                     / \                         
                                                     ---                         
                                                      |                           
             ---------------------------------------------------------------     
             |                    |                      |                 |     
             |                    |                      |                 |     
      --------------       ---------------       --------------       ------------
      |            |1     *|             |1     *|            |1     *|          |
      |   WorldDo  |<------| ContinentDo |<------|  CountryDo |<------|  CityDo  |
      |            |       |             |       |            |       |          |
      --------------       ---------------       --------------       ------------


When using annotations if we retrieve a pointOfSaleDo object and then retrieve the AbstractLocationDo collection we get the following error:
Code:
org.hibernate.WrongClassException: Object with id: 4 was not of the specified subclass: com.....WorldDo (loaded object was of wrong class class com.....CityDo)
   at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1234)     
...                                                                                                                                       


With the "old school" Hibernate mapping files everything works a expected. A collection of locations is retrieved with multiple locations of a different type.

Also when using annotations if we try to retrieve a CityDo location we get the following error (which we don't get when using mapping files):
Code:
SEVERE: IllegalArgumentException in class: com.....StateDo, setter method of property: country
27-sep-2007 14:00:42 org.hibernate.property.BasicPropertyAccessor$BasicSetter set
SEVERE: expected type: com..CountryDo, actual value: com....WorldDo
27-sep-2007 14:00:42 org.hibernate.event.def.DefaultLoadEventListener onLoad
INFO: Error performing load command
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com..StateDo.country
   at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)


Below i'v copied some snippets from the annotation configuration

PointOfSaleDo

Code:
/**
*
* The Point Of Sale class.
*/
@Entity
@Table(name = "Point_Of_Sale")

public class PointOfSaleDo implements DataObject {

<< some fields >>

    /**
     * The collection of allowed origin locations
     */
    private Set<AbstractLocationDo> allowedOrigins;

    /**
     * @return List
     */
    @ManyToMany(targetEntity = AbstractLocationDo.class, cascade = {CascadeType.ALL })
    @JoinTable(name = "ALLOWED_ORIGINS", joinColumns = {@JoinColumn(name = "POINT_OF_SALE_ID") }, inverseJoinColumns = {@JoinColumn(name = "LOCATION_ID") })
    public Set<AbstractLocationDo> getAllowedOrigins() {
        return allowedOrigins;
    }

    /**
     * @param allowedOrigins The collection of allowed origin locations
     */
    public void setAllowedOrigins(Set<AbstractLocationDo> allowedOrigins) {
        this.allowedOrigins = allowedOrigins;
    }
}


AbstractLocationDo
Code:
@Entity
@Table(name = "Location", uniqueConstraints = {@UniqueConstraint(columnNames = {"LOCATION_CODE", "LOCATION_TYPE" }) })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name = "LOCATION_TYPE",
    discriminatorType = DiscriminatorType.STRING, length = 10
)
public abstract class AbstractLocationDo implements DataObject {

<< some field >>

}


CityDo

Code:
@Entity
@DiscriminatorValue("City")
@ForceDiscriminator
public class CityDo extends AbstractStationDo {

    private CountryDo country;

    private Set<AirportDo> airports;

    /**
     *
     * Get airports
     *
     * @return Set
     */
    @OneToMany(mappedBy = "city", cascade = {CascadeType.PERSIST, CascadeType.MERGE })
    public Set<AirportDo> getAirports() {
        return airports;
    }

    /**
     *
     * Get country
     *
     * @return Country
     */
    @ManyToOne
    @JoinColumn(name = "LOCATED_IN_ID")
    public CountryDo getCountry() {
        return country;
    }

    << rest of getters and setters>>
}


Did we do something wrong in the annotations or is there a bug in the annotation processor from hibernate?

Thanks,

Lennard


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 22, 2008 12:44 am 
Newbie

Joined: Mon Aug 14, 2006 8:06 pm
Posts: 18
Location: Montréal, Québec
I experience a similar situation of polymorphism, where "old school" (to use your expression) mappings work, while annotations fail, yielding the same "WrongClassException".

Have you, or anyone else, found a way to solve this using annotations? (Or is this a known annotation shortcoming?)


Top
 Profile  
 
 Post subject: try with @MappedSuperclass
PostPosted: Thu May 22, 2008 2:01 am 
Regular
Regular

Joined: Sun Apr 13, 2008 3:04 am
Posts: 71
Location: Bangalore
Hi,

For the parent class try to use @MappedSuperclass.


Regards,
Nagendra

_________________
Raja Nagendra Kumar,
C.T.O
http://www.tejasoft.com
TejaSoft - Specialists in Code Audit, Unit Testing and Merciless Re-factoring - Engineering Crisis Turnaround Experts


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 22, 2008 3:06 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
@MappedSuperclass is not correct. It is used when the superclass carrying the annotation is NOT mapped.

The only thing I could see from looking at it it the
@ForceDiscriminator Annotation. It really should be on the Abstract Superclass if you need it at all.

We are using this kind of stuff so hibernate is definetly able to do it with annotations.

I guess you already checked that the DiscriminatorValue is unique for the differen subclasses?

Jens Schauder

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 22, 2008 12:00 pm 
Newbie

Joined: Mon Aug 14, 2006 8:06 pm
Posts: 18
Location: Montréal, Québec
Unfortunately, neither of these suggestions works:

with @MappedSuperclass, I get a org.hibernate.InstantiationException: Cannot instantiate abstract class or interface (reminder: the superclass is abstract)

whereas with @ForcedDiscriminator, no row is ever returned, with one of the following exceptions thrown:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists (which is most definitely not the case...)
or org.hibernate.WrongClassException: Object with id: 1981 was not of the specified subclass: com.mystuff.AbstractSuperclass (Discriminator: b)

If I leave out both of these annotations, I get:
org.hibernate.WrongClassException: Object with id: 1981 was not of the specified subclass: com.mystuff.AbstractSuperclass (Discriminator: b)


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 23, 2008 4:48 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Just noted you have the declaration:

public class CityDo extends AbstractStationDo {


But above you where talking about

AbstractLocationDo as the superclass

So which on is the superclass?

With collections with typeparameter you don't need the targetEntity attribute of the annotation by the way

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 24, 2008 5:22 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
Hi,

I don't know why you are using @ForcedDiscriminator (I even didn't know that this annotation exists).

Just wanted to say that I have the same construct which works as expected. Here it is:
Code:
@Entity
@Table(name = "PROJECT", schema="dpjw")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIM", discriminatorType = DiscriminatorType.STRING, length = 2)
public abstract class Project extends EntityBase {
(...)
  @OneToMany(mappedBy="project", cascade = { CascadeType.ALL }, fetch=FetchType.EAGER)
  private Set<Party>parties = new HashSet<Party>();
...

@Entity
@Table(name = "PARTY", schema="dpjw")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIM", discriminatorType = DiscriminatorType.STRING, length = 2)
public abstract class Party extends EntityBase {
...
  @ManyToOne
  @JoinColumn(name = "PROJECT_ID", nullable = false)
  private Project project;
...

and finally the concrete class (which really is the "party")

@Entity
@DiscriminatorValue("S")
public class SingleParty extends Party {



Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 07, 2008 3:14 am 
Newbie

Joined: Tue May 27, 2008 12:35 pm
Posts: 8
Hi lijsselstein,
Did you ever figure this out? I've been stuck on this problem for a few days now! I'm dying here... please let us know if you found a solution. Thank you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.