2010-11-02 29 views
5

Io non sono in grado di eseguire il seguente test: -Gli attributi di metamodello dichiarati funzionano bene MA Gli attributi di Metamodel ereditati sono NULL. Perché?

@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); 
} 

getta NullPointerException a project.get(Project_.lifeCycle) linea. Perché?

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 (generata 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 (solo una parte relavent)

<class>com.comp.timetracking.entity.PersistentEntityBase</class> 
<class>com.comp.timetracking.entity.Project</class> 

EDIT: Io uso hibernate-entitymanager.3.6.0.Final e hibernate-jpamodelgen.1.0.0.Final.

EDIT 2 @Pascal
Penso Hibernate EM 3.6.0.Final ci permette di definire @Embedded campo annotato a livello @Entity ma nega tale campo a livello di @MappedSuperclass. Che ne dici?

Come non riesco a vedere "opzione di caricamento file" qui, ho caricato il TestCase nel mio account esnips. Download il progetto basato su maven ed esegui SingularAttributeTest.java. E checkout l'output della console

ERROR main metamodel.MetadataContext:413 - Unable to locate static metamodel field : timetracking.entity.Employee_#lifeCycle 

Clicca su "Scarica embedded-singular-attribute.zip" link per scaricare il file senza installare il download manager. (Se si fa clic su Download link with Green arrow, sarà necessario installare il download manager !!)

+0

Replica di questa domanda: - https://forum.hibernate.org/viewtopic.php?f=1&t=1008173 – dira

risposta

6

Ho testato le classi e il test case con EclipseLink (ho rimosso le parti specifiche di Hibernate) e le passate di test.Ma in effetti non funziona con Hibernate 3.5.6. Sembra un bug in Hibernate.

A proposito, vi manca un'annotazione Temporal nella vostra Embeddable

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

E non si dovrebbe dichiarare PersistentEntityBase nel persistence.xml (una classe di super-mappata non è un'entità).

+0

+1 Forse cercavi Dovrei usare EclipseLink invece di Hibernate EM? E grazie per le informazioni sull'annotazione @Temporal. – dira

+0

@ becomputer06: In sostanza sto facendo notare che il tuo caso funziona con il RI e che il problema sembra un bug in Hibernate e che dovresti segnalarlo (con un caso di test). Un bug non verrà risolto se nessuno lo segnala. Ma non posso dire se questo problema è abbastanza critico da giustificare il passaggio a un altro provider (non c'è nulla che blocchi IMO, fastidioso sì, blocco no). E altri provider non sono esenti da bug nemmeno. La tua chiamata :) –

+0

checkout la domanda aggiornata. (EDIT 2 parte) – dira

1

Ho avuto lo stesso problema: Durante la distribuzione di JBoss 7.0.2 segnalato il seguente errore: "Impossibile trovare metamodello statica campo X" dove X è un campo ereditato da un @MappedSuperclass e annotato con @Embedded (la il tipo di X è una classe annotata con @Embeddable).

Ho risolto aggiungendo le classi annotate con @Embeddable e @MappedSuperclass, insieme alle classi annotate con @Entity, nell'elenco delle classi che devono essere gestite dall'unità di persistenza. Questo è configurato nel file "persistence.xml".

+1

@Andro Selva anche io sto affrontando lo stesso problema qui. Anche dopo le classi '@ Embeddable' sono registrate nel file' persistence.xml'. – Arunprasad

Problemi correlati