我已将我的 EJB3 代码分解为:
(i) 用于构建“ EJB 客户端 jar ”的业务逻辑接口和 POJO 实体 bean,以及
(ii) 实现业务接口并使用数据库执行 JPA 的业务逻辑代码。
部署的平台是带有 Hibernate JPA 的 JBoss AS7.1。
这个想法是EJB 客户端 jar是接口,它也将与访问业务逻辑代码的一个或多个战争一起部署。我将EJB3业务逻辑代码部署为内部没有WAR的EAR(WAR是独立部署的)。因此,顶层业务逻辑EAR的结构如下:
.
├── lib
│ ├── commons-lang3-3.1.jar
│ └── Users-client.jar
├── META-INF
│ ├── application.xml
│ └── MANIFEST.MF
└── Users-ejb.jar
在我上面的例子中,Users-client.jar是EJB 客户端 jar(接口),而Users-ejb.jar是业务逻辑实现和 JPA 代码。
业务逻辑实现代码(Users-ejb.jar)的结构为:
├── base
│ └── AbstractFacade.class
├── facades
│ ├── PrivateUserDataFacade.class
│ └── UserFacade.class
├── META-INF
│ ├── MANIFEST.MF
│ ├── persistence.xml
│ └── postgres-ds.xml
└── utils
└── JPUtil.class
其中persistence.xml包含以下标签:
<exclude-unlisted-classes>false</exclude-unlisted-classes>
但是,通过上述设置,Users-ejb.jar中的代码无法识别将Users-client.jar定义为实体的 @Entity beans。这不是代码编译和部署时找不到类的问题,而是在运行时引发“非实体”异常。
因此,例如UserFacade.class类中的以下测试方法:
public String boo(String name)
{
javax.persistence.criteria.CriteriaQuery cq =
getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(User.class)); // <-- exception thrown
List<User> all = getEntityManager().createQuery(cq).getResultList();
return "boo"+name;
}
在标有跟踪的地方失败:
Caused by: java.lang.IllegalArgumentException: Not an entity: class entities.User
at org.hibernate.ejb.metamodel.MetamodelImpl.entity(MetamodelImpl.java:158)
[hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.criteria.QueryStructure.from(QueryStructure.java:136)
[hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:177)
[hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at facades.UserFacade.boo(UserFacade.java:46) [Users-ejb.jar:]
我应该怎么做才能确保在 lib/Users-client.jar 中找到的类被我的业务逻辑代码识别为实体?