Everv0id
Everv0id

Reputation: 1982

JPA metamodel fields are null

I have some JPA classes and generate metamodel through org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor. So, one of my classes is:

@Table(name = "USER")
@Entity
@NamedQueries({@NamedQuery(name = "User.byLogin", query = "select u from User u where u.login = :login and u.active = :active")})
public class User implements Serializable {
  @Column(name = "ID")
  @Id
  private Long id;
  @Column(name = "LOGIN")
  private String login;
  @Column(name = "ACTIVE")
  private Boolean active;
  // etc..
}

Metamodel processor generates this:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(User.class)
public abstract class User_ {

    public static volatile SingularAttribute<User, Long> id;
    public static volatile SingularAttribute<User, Boolean> active;
    public static volatile SingularAttribute<User, String> login;

}

Then, there is the following code in my business logic classes:

Map<String, Object> params = new HashMap<String, Object>();
params.put(User_.login.getName(), username);
params.put(User_.active.getName(), Boolean.TRUE);
userDao.executeNamedQuery("User.byLogin", params);

This code crashes with NPE on at the second line. I noticed through debugger that User_ fields are all null. So, the question is: is there a way to initialize these fields? How can i do that?

P.S. This is a legacy code, it worked fine for long time, but now it seems to be broken somehow.

Upvotes: 6

Views: 2103

Answers (2)

mipo256
mipo256

Reputation: 3234

These fields are supposed to be initialized by the persistence provider during initialization. See the documentation (section 6.2.2). The problem most likely is that there is no bootstrapping happening, so no persistence unit creation does occur.

From my experience, that can often happen in unit tests, for instance. It is a very common case when we do not bootstrap the entity manager factory, but in test we rely on that these fields are initialized - they simply do not. But without any additional information, it is hard to say where exactly the problem lies.

UPDATE:

There's a good discussion about how to work this around in tests in this SO thread.

Hope it helped, have a nice day :)

Upvotes: 1

Karol Pokomeda
Karol Pokomeda

Reputation: 141

Parameter values of JPA metamodel are supposed to be null. From what I get it is impossible to get string containing name from User_.login.getName() because User_.login does not exist (is never initialized). User_ is an abstract class, and those values cannot be initialized. The only way to get variable names from metamodel is to get all of them. I'm using following program

public class EntityReader {
    public static<T> String[] getArguments(Class<T> classToRead){
        Field[] fields = classToRead.getFields();
        String[] result = new String[fields.length];
        for (int i = 0; i < fields.length; i++) result[i] = fields[i].getName();
        return result;
    }
}

Upvotes: -1

Related Questions