2010-11-02 19 views
5

no soy capaz de ejecutar la siguiente prueba: -Los atributos de metamodelo declarados funcionan bien PERO los atributos de metamodelo heredado son NULL. ¿Por qué?

@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 project.get(Project_.lifeCycle) línea. ¿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 Generador)

@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: utilizo hibernate-entitymanager.3.6.0.Final y hibernate-jpamodelgen.1.0.0.Final.

EDIT 2 @Pascal
creo Hibernate EM 3.6.0.Final nos permite definir @Embedded campo anotada en @Entity nivel, pero se deniegue dicho campo al @MappedSuperclass nivel. ¿Qué dices?

Como no puedo ver la "opción de carga de archivos" aquí, he subido el TestCase en mi cuenta de esnips. Download el proyecto basado en maven y ejecuta 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 administrador de descargas !!)

+0

réplica de esta pregunta: - https://forum.hibernate.org/viewtopic.php?f=1&t=1008173 – dira

Respuesta

6

Probé sus clases y su caso de prueba con EclipseLink (eliminé las piezas específicas de Hibernate) y las pases de prueba.Pero de hecho falla con Hibernate 3.5.6. Parece un error en Hibernate.

Por cierto, se echa en falta una anotación en su TemporalEmbeddable

@Column(name = "created_date") 
@Temporal(TemporalType.DATE) 
public Date getCreatedDate() { 
    return createdDate; 
} 

Y no se supone que declarar PersistentEntityBase en el persistence.xml (una superclase asignada no es una entidad).

+0

1 Quizás quiso decir Debería usar EclipseLink en lugar de Hibernate EM? Y gracias por la información sobre la anotación @Temporal. – dira

+0

@olvipput06: esencialmente señalo que su caso funciona con RI y que el problema suena como un error en Hibernate y que debe informarlo (con un caso de prueba). Un error no se solucionará si nadie lo informa. Pero no puedo decir si este problema es lo suficientemente crítico como para justificar el cambio a otro proveedor (no hay nada que bloquee a la OMI, sí molesto, no bloqueo). Y otros proveedores tampoco están libres de errores. Tu llamada :) –

+0

presiona la pregunta actualizada. (EDIT 2 parte) – dira

1

que tenían 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 (la tipo de X es una clase anotada con @Embeddable).

Lo resolví agregando las clases anotadas con @Embeddable y @MappedSuperclass, junto con las clases anotadas con @Entity, en la lista de clases que gestionará la unidad de persistencia. Esto se configura en el archivo "persistence.xml".

+1

@Andro Selva también estoy enfrentando el mismo problema aquí. Incluso después de que las clases '@ Embeddable' están registradas en el archivo' persistence.xml'. – Arunprasad

Cuestiones relacionadas