Issue #840: Super class' field access fails

Type: Bug ReoprtVersion: 2.4.1Priority: NormalStatus: ClosedReplies: 6
#1

I have a base class:

public abstract class HotObject extends BaseObject {

  private Integer activity;

  protected HotObject() {
    activity = 1;
  }

  public Integer getActivity() {
    return activity;
  }

  public void setActivity(Integer activity) {
    this.activity = activity;
  }

  public void increaseActivity() {
    activity += 1;
  }

  protected abstract Integer getDecrease();

  public Boolean decreaseActivity() {
    Integer adaptedDecrease;
    if (activity < 50) {
      adaptedDecrease = getDecrease();
    } else if (activity < 100) {
      adaptedDecrease = getDecrease() + 5;
    } else {
      adaptedDecrease = getDecrease() + 10;
    }
    activity = activity - ((activity * adaptedDecrease) / 100) - 1;
    return activity < 2;
  }
}

 

And I have an inherited class:

@Entity
public class HotTag extends HotObject implements Serializable {

  private static final Integer decrease = 20; // percent
  //
  @Id
  private String name;

  public HotTag() {
  }

  public HotTag(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  @Override
  protected Integer getDecrease() {
    return decrease;
  }
}

Now, when issuing the following query:

TypedQuery<HotTag> query = em.createQuery("SELECT t FROM HotTag t ORDER BY t.activity DESC", HotTag.class);

I get the exception (in objectdb 2.4.1):

com.objectdb.o.UserException: Field 'activity' is not found in type 'net.pocketservices.athene.objects.persistent.HotTag'

 

This can only be resolved by changing

private Integer activity;

to

public Integer activity;

in the super class. This looks like a bug to me. Normally, private access is not an issue with objectdb. I do queries on private fields all the time... So, when querying a private inherited field, I would expect this to work as well. Or is this according to the JPA spec? Then forgive me asking a stupid question.. :)

Thanks for insight!

Best, Benjamin

 

#2

Please check the following test case that works:

import javax.persistence.*;

public class T840 {

    public static void main(String[] args) {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:d:\\temp\\test.tmp;drop");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        em.persist(new B());
        em.getTransaction().commit();
       
        em.createQuery("SELECT b FROM B b ORDER BY b.x DESC").getResultList();

        em.close();
        emf.close();
    }

    @Entity
    public abstract static class A {
        private Integer x;
    }
   
    @Entity
    public static class B extends A {
    }
}

Try to change it to reproduce the error message that you got.

In general, you should follow the posting instructions and post a test case to demonstrate an issue.

ObjectDB Support
#3

Thank you for your quick reply. One thing that I realize immediately is that you defined the base class to be an @Entity as well. Something I cannot do, as the primary key is only defined by the inherited class. So I left out the @Entity annotation in the base class.

Best, Benjamin

 

#4

Hm.. maybe I was fooled by NetBeans. It is complaining about the missing id field in the base class. But the code compiles nevertheless and works also. So this was the problem: The missing @Entity annotation in the base class. Seems NetBeans has a bug here? Or is there a JPA annotation available to tell that the id field is only added in inherited classes?

 

#5

If the base class is not an entity then its fields are not persistent and the error message is right.

Actually, ObjectDB should be fixed to produce a similar error also when the inherited field is public.

To avoid the NetBeans error - try annotating the base abstract class as @MappedSuperclass (instead of as @Entity).

ObjectDB Support
#6

Screenshot attached with the NetBeans indication that the code would be wrong.

#7

Thanks so much! Problem solved! 

Reply