Paddy
Paddy

Reputation: 3630

JPQL unable to create a list of objects of base class (abstract) of an inheritance hierarchy


We have an inheritance hierarchy say like this:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@NamedQuery("select NEW package.BaseClass(bc.field1, bc.field2) from BaseClass b")
public abstract BaseClass {
   public BaseClass(int field1, String field2) {
   }
}

@Entity
public SubClass1 extends BaseClass {
}

and similarly SubClass2

Now the problem I face is with the @NamedQuery syntax here, which does not allow me to create List objects because it cannot instantiate BaseClass using constructor. So can anyone suggest how to solve this while leaving the named query in base class itself?

Or please tell me if there is a way to exclude a column in the select as in

select bc.*Field3 from BaseClass

or some syntax like that prevents the lazy loading of association field3 that I don't need in this case?

Upvotes: 0

Views: 128

Answers (1)

Predrag Maric
Predrag Maric

Reputation: 24433

You are using some things here in a strange way.

First, JPQL constructor expressions are normally used with non-entity classes. You can have some non-entity class with two fields (field1 and field2) and a matching constructor and use that in place of package.BaseClass in your @NamedQuery, and it should work. I don't see a point in using an entity class here. If you expected to get a list of BaseClass entities with only field1 and field2 initialized, that's just not how it works. But select bc.field1, bc.field2 from BaseClass b will work, but it will give a tuple as a result, not entities.

Also, @OneToOne and @ManyToOne are by default eagerly fetched, so that might be the reason for additional query firing that you see. Set it explicitly to be FetchType.LAZY and it should be ok.

Regarding this

how to solve this while leaving the named query in base class itself

you don't have to keep the named query in the base class, you can put it in whatever entity you want. An often used option is to have one "fake" entity that will hold all named queries at one place. Check out this answer for an example.

Upvotes: 1

Related Questions