7

I know there are some post about this, but they are about a year and no response. Actually we are using Hibernate 4.2.1.Final over PostgreSQL 8.4. We have two entitys like this

Entity A (Top Hierarchy Class)

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Polymorphism(type = PolymorphismType.EXPLICIT)
public class A {
    @Id
    @GeneratedValue
    private Long id;

    public A() {

    }

    public A(Long id) {
        super();
        this.id = id;
    }

    // Setters, getteres, hashCode and equals
}

Entity B (Subclass)

@Entity
public class B extends A{
    String value;

    public B(){

    }

    public B(String value) {
        super();
        this.value = value;
    }

    public B(Long id, String value) {
        super(id);
        this.value = value;
    }

    // Setters, getteres, hashCode and equals
}

As you can see, A entity is annotated with PolymorphismType.EXPLICIT but when fetching the top class with

ArrayList<A> lista = (ArrayList<A>) session.createCriteria(A.class).list();

we are getting the B subclasses too with the String value property. In fact, the SQL statement contains left outer join B. Is this still a bug in the fourth version of Hibernate or I'm doing something wrong?

Best regards

hespresati
  • 187
  • 3
  • 19

1 Answers1

6

In my opinion, the relevant documentation and the feature itself is very confusing. From Chapter 5:

Explicit polymorphisms means that class instances will be returned only by queries that explicitly name that class.

which would indicate to me that your query should work. But what you're trying to do does not appear to be their intention, as you can see later in the same paragraph:

Explicit polymorphisms is useful when two different classes are mapped to the same table This allows a "lightweight" class that contains a subset of the table columns.

What they're talking about here is having B and A map to the same table, but have no actual class relationship. You can see this opinion repeated in an old JIRA ticket. I guess that means that if they didn't have a class relationship, but are in the same table, then you could use IMPLICIT polymorphism to get both with the same query, but that seems totally bizarre given they don't share a Java subclass.

So, the summary is that PolymorphismType.EXPLICIT doesn't do what you think it does. In my opinion, it should do what you're expecting, based on the first above quote.

sharakan
  • 6,821
  • 1
  • 34
  • 61
  • 1
    Yes, the documentation is very confusing and should be clarified. So now, the question is knowing that we're using _table per subclass_ instead of having A and B in the same table (because the real schema is not so simple), there's a way to fetch only A entitys without fetching all data and composing the response creating A instances manually? I mean, a `SELECT` SQL statement without `left outer join B`. Thank you – hespresati Jun 25 '13 at 08:01
  • Can you break the inheritance link between A and B? – sharakan Jun 25 '13 at 11:06
  • I think we can't. The real legacy schema is a tree like Conact, Company that extends Contact and Person that extends Contact. And there are another entitys that extends from Company, more entitys tha extends from Person and so on – hespresati Jun 25 '13 at 13:20
  • 3
    The way I've dealt with similar situations in the past is to make the higher level shared subclass be a `@MappedSuperclass`, and my queries are on subclasses. So from the database point of view, there's no real relationship between, say, Company and Person. So perhaps you want to transform Contact in to a `@MappedSuperclass`, and only query on Person and Company? – sharakan Jun 25 '13 at 14:36
  • That was one of the aproachs I was thinking but we will have the same problem when querying to Company or Person. Fired SQL statements will have joins with subclasses – hespresati Jun 25 '13 at 15:17
  • That's one of the disadvantages listed with table-per-subclass. If you want to avoid it, perhaps you want to move to table-per-class hierarchy – sharakan Jun 25 '13 at 15:28
  • The joins in subclasses are ok when fetching them. The problem is when querying the top class. Even with `@MappedSuperclass` the problem will persist. We decided to go through _table-per-subclass_ with the explicit polymorphism goal in mind, just querying the single table. Thanks for your help. I'll keep working on this. Best regards – hespresati Jun 27 '13 at 09:29
  • 1
    @hespresati It is **possible** (not sure about this) that if you put EXPLICIT in the subclasses, your queries will work out the way you want. Another way of doing this (which may be better) is to move from inheritance to composition: model your top level class as a container of the subclasses, have the entity association be lazily loaded. – sharakan Jun 27 '13 at 14:09
  • Are there any drawbacks when using PolymorphismType.EXPLICIT? – svlada Apr 19 '15 at 18:08