2

I have some tables that have some common columns and I thought that when creating entities I would have the entities extend a class where all of the mapping is defined:

@MappedSuperclass
public class AbstractLogMaster implements Serializable
{
  @Id
  @Basic(optional = false)
  @Column("id")
  protected long id;

  @Column("field1")
  protected String field1;

  @Column("field2")
  protected String field2;

  public long getId()
  {
    return id;
  }

  public void setId(long id)
  {
    this.id = id;
  }

  etc...
}

@Entity
@Table(name = "logwork")
public class LogWork extends AbstractLogMaster implements Serializable
{
  @Column("field3")
  protected int field3;

  public int getField3()
  {
    return field3;
  }
}

Using this in a query Predicate p1 = builder.equal(logWork.get(LogWork_.field1), f1); results in a NPE (specifically because of the logWork.get(LogWork_.field1) part - the @StaticMetaModel doesn't seem to work with mapped superclass)

Looking at the JPA documentation I discovered that:

Mapped superclasses cannot be queried and can’t be used in EntityManager or Query operations. You must use entity subclasses of the mapped superclass in EntityManager or Query operations. Mapped superclasses can’t be targets of entity relationships. Mapped superclasses can be abstract or concrete.

Does this mean that none of the fields I map in the mapped superclass are available to be used by the extending entities in criteria queries? If so, what is the point of putting mapping into the superclass?? If not, what am I doing wrong??

KidTempo
  • 910
  • 1
  • 6
  • 22
  • 1
    It's been a while since I played with JPA, but I believe it's saying that mappings can be inherited but you can't generically use them to query - meaning if you have a superclass `SuperMan` and a class that extends it, call it `SuperChild`, you have to do all your queries on `SuperChild` – StormeHawke Oct 11 '13 at 15:08
  • You can use fields of a mapped super class in queries, StormeHawke is correct. Problem will be in `logWork.get(LogWork_.field1)`. How does it work, is it based on reflection? – Mareen Oct 11 '13 at 15:33
  • @Mareen LogWork_.field1 comes from a '@StaticMetamodel(LogWork.class)' annotated companion class which provides aliases for the criteria query/builder. It works by "magic" (actually, probably by reflection) – KidTempo Oct 11 '13 at 15:48

1 Answers1

0

My bad. Turns out the answer to this question is the "proper" use of the @StaticMetamodel annotated companion classes. The mapped superclasses must all have individual static metamodels that inherit in the same way (I had bundled everything for the entity into one metamodel, LogWork_)

@StaticMetamodel(AbstractLogMaster.class)
public final class AbstractLogMaster_
{
  public static volatile SingularAttribute<AbstractLogMaster, Long> id;
  public static volatile SingularAttribute<AbstractLogMaster, String> field1;
  public static volatile SingularAttribute<AbstractLogMaster, String> field2;
}

@StaticMetamodel(LogWork.class)
public final class LogWork_ extends AbstractLogMaster_
{
  public static volatile SingularAttribute<LogWork, Integer> field3;
}
KidTempo
  • 910
  • 1
  • 6
  • 22