5

I am not able to run the following 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);
}

it throws NullPointerException at project.get(Project_.lifeCycle) line. Why?

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 (Generated using 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 (only relavent part)

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

EDIT: I use hibernate-entitymanager.3.6.0.Final and hibernate-jpamodelgen.1.0.0.Final.

EDIT 2 @Pascal
I think Hibernate EM 3.6.0.Final allows us to define @Embedded annotated field at @Entity level but it denies such field at @MappedSuperclass level. What do you say?

As I cannot see "file upload option" here, I've uploaded the TestCase in my esnips account. Download the maven-based-project and run SingularAttributeTest.java. And checkout the console output

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

Click on "Download embedded-singular-attribute.zip" link to download the file WITHOUT installing the download manager. (If you click on Download link with Green arrow, you'll have to install the download manager!!)

dira
  • 30,304
  • 14
  • 54
  • 69
  • Replica of this question :- https://forum.hibernate.org/viewtopic.php?f=1&t=1008173 – dira Nov 12 '10 at 07:27

3 Answers3

6

I tested your classes and test case with EclipseLink (I removed the Hibernate specific parts) and the test passes. But it indeed fails with Hibernate 3.5.6. Looks like a bug in Hibernate.

By the way, you are missing a Temporal annotation in your Embeddable

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

And you are not supposed to declare PersistentEntityBase in the persistence.xml (a mapped super class is not an entity).

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • +1 Did you mean I should use EclipseLink instead of Hibernate EM? And thanks for the info about @Temporal annotation. – dira Nov 12 '10 at 07:27
  • @becomputer06: I'm essentially pointing out that your case works with the RI and that the problem sound like a bug in Hibernate and that you should report it (with a test case). A bug won't get fixed if nobody reports it. But I can't say if this problem is critical enough for you to justify moving to another provider (there is nothing blocking IMO, annoying yes, blocking no). And other providers are not free of bugs neither. Your call :) – Pascal Thivent Nov 12 '10 at 08:05
2

this is not an issue.

From Hibernate documentation:

If class X extends another class S, where S is the most derived managed class (i.e., entity or mapped superclass) extended by X, then class X_ must extend class S_, where S_ is the metamodel class created for S.

https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/metamodel.html

Nikolay Shabak
  • 576
  • 1
  • 7
  • 18
1

I had the same problem: During deployment the jboss 7.0.2 reported the following error: "Unable to locate static metamodel field X" where X is a field inherited from a @MappedSuperclass and annotated with @Embedded (the type of X is a class annotated with @Embeddable).

I solved it adding the classes annotated with @Embeddable and @MappedSuperclass, together with the classes annotated with @Entity, in the list of classes to be managed by the persistence unit. This is configured in the "persistence.xml" file.

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
Gustavo
  • 11
  • 2
  • 1
    @Andro Selva i'm also facing same problem over here .even after `@Embeddable` classes are registered in `persistence.xml` file. – Arunprasad Oct 08 '14 at 06:49