当我将Java EE应用程序部署到Glassfish时,我有一个非常好奇的问题。我有一个Eclipse EAR项目,它引用了一个Web项目(包含一个Servlet)和一个EJB项目(拥有一个EJB)和一个JPA项目(拥有一个@Entity)。在我的servlet我调用EJB,又执行下面的查询:JPA实体类实例
final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<Country> criteriaQuery = criteriaBuilder.createQuery(Country.class);
final Root<Country> root = criteriaQuery.from(Country.class);
在上面的代码中的第三行我得到一个异常:
Severe: java.lang.IllegalArgumentException: Not an entity: class <package>.entity.Country
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)
at org.hibernate.jpa.criteria.QueryStructure.from(QueryStructure.java:139)
at org.hibernate.jpa.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:173)
at <package>.CountrySessionBean.getCountries(CountrySessionBean.java:35)
...
我已经调试上述休眠类,即MetamodelImpl,并且我看到它已经注册了我的实体(在实体Map中)。类名与我所要求的一样(净...国家)完全相同。然而,这个类是从下面的代码,我在servlet中放置不同:
final Class<?> countryClass = Country.class;
我说这是“不同”,因为“declaredConstructors”字段和“declaredPublicMethods”是不同的。在servlet中,这些字段为'null'(奇怪,请参阅下面的Country.java!),但在MetamodelImpl类中,这些字段包含我在实体中定义的构造函数和公共方法。由于MetamodelImpl使用Map,因为“class”不同(即存储在内存中的不同位置),所以它无法在注册的类中找到实体,当然它会抛出IllegalArgumentException。我已经检查过,部署到Glassfish的东西只包含一个Country.class文件,所以这真的令人困惑,为什么同一个类有两个不同的Class实例,并且它们彼此不同!
任何人有什么想法?
仅供参考:Hibernate v4.3.6,EJB v3.2,Glassfish v4.1,JPA v2.1。
My Country.java实体在下面。正如你所看到的,它包含一个构造函数和公共方法,所以令我惊讶的是,在servlet中,类没有“declaredConstructors”或“declaredPublicMethods”。怎么会这样?
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
@Entity
public class Country implements Serializable {
private static final long serialVersionUID = -3119088680575312729L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Pattern(regexp = ".[\\p{L} \\.\\[\\]\\?\\-\\(\\)]{1,30}+")
@NotNull
private String name;
public Country() {
super();
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public Integer getId() {
return this.id;
}
public void setId(final Integer id) {
this.id = id;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(this.name);
builder.append(" (");
builder.append(this.id);
builder.append(")");
return builder.toString();
}
}
JPA有时是一个烂摊子。1.声明的实体persistence.xml,或者2.确保它们和ejb – maress 2014-10-07 15:04:13
在同一个jar里谢谢,我也试过了,t无法在EJB项目中创建最简单的实体,只需一个空的公共构造函数就可以创建一个id和一个getter/setter。然后在EJB代码中,我检查这个类,它与MetamodelImpl中注册的类不同。在我用MyEntity.class引用它的时候,我在构造函数中定义的类以及运行时的getters和setter类没有任何构造函数或方法,这没有任何意义。这些声明哪里去了? – Raoul 2014-10-08 06:53:15