metamodelo declarado atributos funcionan bien pero los atributos heredados Metamodel son nulos. ¿Por qué?
-
28-09-2019 - |
Pregunta
No soy capaz de ejecutar la siguiente prueba: -
@Test
public void test() {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Project> query = builder.createQuery(Project.class);
Root<Project> project = query.from(Project.class);
Path<String> name = project.get(Project_.name);
Assert.assertNotNull(name);
Path<EntityLifeCycleImpl> lifeCycle = project.get(Project_.lifeCycle); // problem is here, throws NullPointer
Assert.assertNotNull(lifeCycle);
}
arroja NullPointerException en la línea project.get(Project_.lifeCycle)
. ¿Por qué?
java.lang.NullPointerException
at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:138)
PersistenceEntityBase.java
import org.hibernate.annotations.GenericGenerator;
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class PersistentEntityBase {
protected String identifier;
protected EntityLifeCycleImpl lifeCycle = new EntityLifeCycleImpl();
protected PersistentEntityBase() {
}
@Id
@GeneratedValue(generator="generator")
@GenericGenerator(name="generator", strategy="guid", parameters = {})
@Column(name="identifier")
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
@Embedded
public EntityLifeCycleImpl getLifeCycle() {
return lifeCycle;
}
public void setLifeCycle(EntityLifeCycleImpl lifeCycle) {
this.lifeCycle = lifeCycle;
}
}
Project.java
@Entity
@Table(name="project")
@Access(AccessType.PROPERTY)
public class Project extends PersistentEntityBase {
private String name;
protected Project() {
}
public Project(String name) {
this();
this.name = name;
}
@Column(name="name", nullable=false, unique=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
EntityLifeCycleImpl.java
@Embeddable
public class EntityLifeCycleImpl implements EntityLifeCycle {
private String createdBy;
private Date createdDate;
@Column(name="created_by")
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
@Column(name="created_date")
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
}
PersistentEntityBase_.java (generada usando Hibernate Metamodel Generator)
@StaticMetamodel(PersistentEntityBase.class)
public abstract class PersistentEntityBase_ {
public static volatile SingularAttribute<PersistentEntityBase, EntityLifeCycleImpl> lifeCycle;
public static volatile SingularAttribute<PersistentEntityBase, String> identifier;
}
Project_.java
@StaticMetamodel(Project.class)
public abstract class Project_ extends PersistentEntityBase_ {
public static volatile SingularAttribute<Project, String> name;
}
EntityLifeCycleImpl_.java
@StaticMetamodel(EntityLifeCycleImpl.class)
public abstract class EntityLifeCycleImpl_ {
public static volatile SingularAttribute<EntityLifeCycleImpl, String> createdBy;
public static volatile SingularAttribute<EntityLifeCycleImpl, Date> createdDate;
}
persistence.xml (sólo parte relavent)
<class>com.comp.timetracking.entity.PersistentEntityBase</class>
<class>com.comp.timetracking.entity.Project</class>
EDIT: Yo uso hibernate-entitymanager.3.6.0.Final y hibernate-jpamodelgen.1.0.0.Final.
EDIT 2
@Pascal
Creo que Hibernate EM 3.6.0.Final nos permite definir el campo anotado @Embedded
a nivel @Entity
pero niega dicha materia a nivel @MappedSuperclass
. ¿Qué dice usted?
Como no puedo ver "la opción de carga de archivos" aquí, he subido su TestCase en mi cuenta de esnips. Descarga el experto o basadas proyecto y ejecute SingularAttributeTest.java
. Y la salida de la salida de la consola
ERROR main metamodel.MetadataContext:413 - Unable to locate static metamodel field : timetracking.entity.Employee_#lifeCycle
Haga clic en " Descargar embedded-singular-attribute.zip" enlace para descargar el archivo sin necesidad de instalar el gestor de descargas. (Si hace clic en Download link with Green arrow
, tendrá que instalar el gestor de descargas !!)
Solución
Probé sus clases y caso de prueba con EclipseLink (I quitado las partes específicas de Hibernate) y se pasa la prueba. Pero de hecho no con Hibernate 3.5.6. Se parece a un error en Hibernate.
Por cierto, se echa en falta una anotación en su Temporal
Embeddable
@Column(name = "created_date")
@Temporal(TemporalType.DATE)
public Date getCreatedDate() {
return createdDate;
}
Y que se supone que no PersistentEntityBase
declarar en el persistence.xml
(una superclase asignada no es una entidad).
Otros consejos
Yo tenía el mismo problema: Durante el despliegue del JBoss 7.0.2 reportó el siguiente error: "No se puede localizar metamodelo estática campo X" donde X es un campo heredado de un @MappedSuperclass y anotado con @Embedded (el tipo de X es una clase anotada con @Embeddable).
Lo resuelto añadiendo las clases con anotada y @Embeddable @MappedSuperclass, junto con las clases anotadas con @Entity, en la lista de clases que será gestionado por la unidad de persistencia. Esto se configura en el archivo "persistence.xml
".
esto no es un problema.
A partir de la documentación de Hibernate:
Si la clase X se extiende otra clase S, donde S es la clase administrada más derivada (es decir, entidad o superclase asignada) prolongada por X, entonces X_ clase deben extenderse S_ clase, donde S_ es la clase metamodelo creado para S.
https://docs.jboss.org/ Hibernate / EntityManager / 3,5 / referencia / en / html / metamodel.html