當我將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