JEE / JPA - 如何使用其他项目中的DAO / CRUD-基类和实体(Eclipse)

时间:2018-03-24 03:18:21

标签: java jpa java-ee eclipselink jpa-2.0

未来有多个问题。 这段代码工作正常。

我在Eclipse工作。 从整个设置中可以看出,我正在使用JTA。

项目布局

Local Project
 - servlets
    - _Index (using User)
    - _Index2 (using Person)
 - cruds
    - UserCRUD
    - PersonCRUD
 - entities
    - User

Remote/Other/Library Project
 - entities
    - Person

的persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="default" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/test</jta-data-source>
        <class>tests.jee.simple.entities.User</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
            <property name="javax.persistence.schema-generation.database.action" value="create" />
            <property name="javax.persistence.schema-generation.scripts.action" value="create" />
            <property name="javax.persistence.schema-generation.create-source" value="metadata-then-script" />
            <property name="javax.persistence.schema-generation.drop-source" value="script-then-metadata" />
        </properties>
    </persistence-unit>
</persistence>

的Servlet

@WebServlet("/")
public class _Index extends HttpServlet {
    private static final long serialVersionUID = -2039252988955365999L;

    @EJB private UserCRUD mUserCRUD;

    @Override protected void doGet(final HttpServletRequest pReq, final HttpServletResponse pResp) throws IOException {
        final User u = new User();
        u.setName("User #" + ((int) (Math.random() * 1000)));
        mUserCRUD.persist(u);

        pResp.getWriter().write("<pre>");
        final List<User> all = mUserCRUD.getAll();
        for (final User user : all) {
            pResp.getWriter().write("\t" + user + "\r\n");
        }
        pResp.getWriter().write("</pre>");
    }
}

实体:

@Entity
public class User {
    @Id @GeneratedValue private long    id;
    private String                      name;

    public String getName() {
        return name;
    }
    public void setName(final String pName) {
        name = pName;
    }
    @Override public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}

CRUD / DAO / EJB:

@Stateless
public class UserCRUD {
    @PersistenceContext private EntityManager mEM;

    public void persist(final User pUser) {
        mEM.persist(pUser);
    }
    public List<User> getAll() {
        final TypedQuery<User> query = mEM.createQuery("SELECT i FROM " + User.class.getSimpleName() + " i", User.class);
        return query.getResultList();
    }
}

现在我想使用其他Eclipse项目中的实体。

其他项目中的班级人员

@Entity
@Table(name = "Company_Person")
public class Person {
    @Id @GeneratedValue private long mId;
    private String  mName;
    public Person() {}

    public void setName(final String pName) {
        mName = pName;
    }
    public String getName() {
        return mName;
    }
}

在本地项目中的CRUD,就在UserCRUD旁边:

@Stateless
public class PersonCRUD {
    @PersistenceContext private EntityManager mEM;

    public void persist(final Person pUser) {
        mEM.persist(pUser);
    }
    public List<Person> getAll() {
        final TypedQuery<Person> query = mEM.createQuery("SELECT i FROM " + Person.class.getSimpleName() + " i", Person.class);
        return query.getResultList();
    }
}

本地项目中的Servlet#2

@WebServlet("/2")
public class _Index2 extends HttpServlet {
    private static final long serialVersionUID = -2039252988955365999L;

    @EJB private PersonCRUD mPersonCRUD;

    @Override protected void doGet(final HttpServletRequest pReq, final HttpServletResponse pResp) throws IOException {
        final Person u = new Person();
        u.setName("User #" + ((int) (Math.random() * 1000)));
        mPersonCRUD.persist(u);

        pResp.getWriter().write("<pre>");
        final List<Person> all = mPersonCRUD.getAll();
        for (final Person user : all) {
            pResp.getWriter().write("\t" + user + "\r\n");
        }
        pResp.getWriter().write("</pre>");
    }
}

但是一旦我开始引用其他项目中的类(包括然后在构建路径中),JPA就变得很奇怪了:

首先,它告诉我部署时,其他CRUD的JNDI查找失败:

  

2018-03-23T17:43:41.835 + 0100 |严重:部署应用程序时出现异常[Test_JEE_Simple]:资源的JNDI查找失败:名称:[java:module / env / tests.jee.simple.servlets。 _Index2 / mPersonCRUD],查找:[tests.jee.simple.crud.PersonCRUD#tests.jee.simple.crud.PersonCRUD],输入:[Session]   javax.naming.NamingException:SerialContext中的'tests.jee.simple.crud.PersonCRUD#tests.jee.simple.crud.PersonCRUD'查找失败[myEnv = {java.naming.factory.initial = com.sun.enterprise。 naming.impl.SerialInitContextFactory,java.naming.factory.state = com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl,java.naming.factory.url.pkgs = com.sun.enterprise.naming} [Root异常是javax.naming.NameNotFoundException:tests.jee.simple.crud.PersonCRUD#tests.jee.simple.crud.PersonCRUD not found]

JPA不会自动从其他项目中找到类,而是抛出ClassNotFoundExceptions。

所以我将相关项目添加到Project->Properties->Deployment Assembly。 访问用户(/Test_JEE_Simple/ => _Index.class)工作正常。 访问用户(/Test_JEE_Simple/2 => _Index2.class)不起作用,抛出

  

引起:java.lang.IllegalArgumentException:对象:用户#706(null / null)不是已知的实体类型。

当我尝试将Person.class添加到persistence.xml条目时,仍然存在同样的问题。

所以我的问题在这里:

  1. 是否可以仅使用JTA,或者我必须在某个时候使用RESOURCE_LOCAL?
  2. 有没有办法在另一个项目中使用PersonCRUD?
  3. 通常我使用crud基类,如果需要,特定类(如UserCRUD和PersonCRUD)会扩展它。工作得很好。不想编写大量的样板代码,但使用该方法仍然可以处理特定的请求。那么:甚至可以在另一个项目中使用那个通用的CRUD-Class吗?
  4. 有没有办法(注释等)使用JTA的EntityManager事务?我在某个地方看到了一个技巧,但是没有测试并保存它,所以它输给了我......
  5. 更新 出于一些神奇的原因(并且似乎有很多魔法)我现在可以使用来自其他类的实体...在我在本地项目中添加其他项目部署程序集,取消部署,清理,关闭,重新打开和部署之后的某个时间发生了当地的项目...

    所以现在剩下的问题是2-4,理想的布局:

    Local Project (referencing lib #1 and lib #2)
     - servlets
        - _Index (using User)
        - _Index2 (using Person)
     - cruds
        - UserCRUD: CrudBase<User>
     - entities
        - User
    
    Remote/Other/Library Project #1 (referencing lib #2)
     - entities
        - Person
     - cruds
        - PersonCRUD: CrudBase<Person>
    
    Remote/Other/Library Project #2 (super-library)
     - cruds
        - CrudBase<T>
    

0 个答案:

没有答案