7

Suppose a Table per subclass inheritance relationship which can be described bellow (From wikibooks.org - see here)

Notice Parent class is not abstract

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Project {

    @Id
    private long id;

    // Other properties

}

@Entity
@Table(name="LARGEPROJECT")
public class LargeProject extends Project {

    private BigDecimal budget;

}

@Entity
@Table(name="SMALLPROJECT")
public class SmallProject extends Project {

}

I have a scenario where i just need to retrieve the Parent class. Because of performance issues, What should i do to run a HQL query in order to retrieve the Parent class and just the Parent class without loading any subclass ???

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136

3 Answers3

8

A workaround is described below:

Define your Parent class as MappedSuperClass. Let's suppose the parent class is mapped To PARENT_TABLE

@MappedSuperClass
public abstract class AbstractParent implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @Column(table="PARENT_TABLE")        
    private String someProperty;

    // getter's and setter's

}

For each subclass, extend the AbstractParent class and define its SecondaryTable. Any persistent field defined in the parent class will be mapped to the table defined by SecondaryTable. And finally, use AttributeOverrides if needed

@Entity
@SecondaryTable("PARENT_TABLE")
public class Child extends AbstractParent {

    private String childField;

    public String getChildProperty() {
        return childField;
    }

}

And define another Entity with the purpose of retrieving just the parent class

@Entity
@Table(name="PARENT_TABLE")
@AttributeOverrides({
    @AttributeOverride(name="someProperty", column=@Column(name="someProperty"))
})
public class Parent extends AbstractParent {}

Nothing else. See as shown above i have used just JPA specific annotations

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
  • Good idea, but I was wondering if this can be achieved by using InheritanceType.JOINED? I have read that following annoatation can be used on root entity @Polymorphism(type = PolymorphismType.EXPLICIT). I have tried that with no luck however. – svlada Apr 19 '15 at 19:26
  • I have the same problem and using Hibernate 4.3.7 .. by using InheritanceType.JOINED want to retrieve data only from the parent class... @svlada so do you have any solution for that? – Nebras Apr 27 '16 at 09:18
4

Update: It appears the first option doesn't work as I thought.

First option:

Specify the class in the where clause:

select p from Project p where p.class = Project 

Second option:

Use explicit polymorphism that you can set using Hibernate's @Entity annotation:

@javax.persistence.Entity
@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)
@Inheritance(strategy = InheritanceType.JOINED)
public class Project {

    @Id
    private long id;
    ...
}

This is what Hibernate Core documentation writes about explicit polymorphism:

Implicit polymorphism means that instances of the class will be returned by a query that names any superclass or implemented interface or class, and that instances of any subclass of the class will be returned by a query that names the class itself. Explicit polymorphism means that class instances will be returned only by queries that explicitly name that class.

See also

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • @Pascal Thivent Thank you for your reply but The first approach shown by yourself "left inner join" **all of subclasses** (You can test if you want). And i just need to retrieve **just** The Parent class - select ... from Project where p.id = :id without no "left inner join" with any subclass – Arthur Ronald May 07 '10 at 04:50
  • @Arthur I thought I tested this but I believe you. Will take a second look later in the day... – Pascal Thivent May 07 '10 at 05:08
0

Actually, there is a way to get just the superclass, you just need to use the native query from JPA, in my case I'm using JPA Repositories it would be something like that:

@Query(value = "SELECT * FROM project", nativeQuery = true)
List<Resource> findAllProject();

The flag nativeQuery as true allow running the native SQL on database.

If you are using Entity Manager check this out: https://www.thoughts-on-java.org/jpa-native-queries/