JPA metamodel fields are null
Asked Answered
U

2

6

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.

Unfounded answered 20/4, 2016 at 13:36 Comment(4)
JPA metamodel is meant to be used only in Criteria queries as explained here. I am not sure whether it can be used in the parameters construction of a named query at all. Also note that the usage is completely different from yoursRafael
@Rafael i understand. The only thing i dont understand is that it worked somehow before. So there are big amounts of similar legacy code, and i wonder if there a way to fix it without rewriting all of that.Unfounded
Does this answer your question? Static Metamodel attributes null when unit testingResistive
@VladislavVarslavans Sorry, I cannot confirm - I don't work with JPA anymore.Unfounded
B
0

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 not bootstrapping happening, no persistence unit creation does not 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 :)

Benavidez answered 6/9, 2024 at 12:22 Comment(0)
T
-1

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;
    }
}
Tallulah answered 17/5, 2017 at 13:54 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.