metamodel dichiarato attributi funzionano bene ma gli attributi Metamodel ereditati sono nulli. Perché?

StackOverflow https://stackoverflow.com/questions/4077075

Domanda

Io non sono in grado di eseguire il seguente test: -

@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 alla linea project.get(Project_.lifeCycle). 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 (generati 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>

Modifica Io uso hibernate-entitymanager.3.6.0.Final e hibernate-jpamodelgen.1.0.0.Final.

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

Come non riesco a vedere "l'opzione di upload di file" qui, ho caricato il TestCase nel mio account esnips. Scarica l'esperto-based- progetto e SingularAttributeTest.java corsa. E checkout l'output della console

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

Fare clic 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, dovrete installare il download manager !!)

È stato utile?

Soluzione

Ho testato le vostre classi e banco di prova con EclipseLink (ho tolto le parti specifiche Hibernate) e il test viene superato. Ma in effetti non riesce con Hibernate 3.5.6. Si presenta come 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 è dovuto dichiarare PersistentEntityBase nel persistence.xml (una classe di super-mappata non è un'entità).

Altri suggerimenti

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

I risolto aggiungendo le classi annotate con @Embeddable e @MappedSuperclass, insieme con le classi annotate con @Entity, nell'elenco delle classi da gestire dall'unità di persistenza. Questo è configurata nel file "persistence.xml".

questo non è un problema.

Da documentazione Hibernate:

  

Se la classe X estende un'altra classe S, dove S è la classe gestita massima derivazione (cioè, entità o superclasse mappata) esteso dal X, allora classe X_ devono estendersi classe S_, dove S_ è la classe metamodello creato per S.

https://docs.jboss.org/ hibernate / EntityManager / 3.5 / riferimento / it / html / metamodel.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top