JEE/JPA:如何在Eclipse中使用DAO/CRUD基类及其他项目实体
Hey there! Since your Eclipse-based JTA project is already running smoothly, let's walk through how to build a reusable DAO/CRUD base class and properly work with entities from a remote project. Here's a step-by-step breakdown tailored to your setup:
1. Build a Generic DAO/CRUD Base Class
The goal here is to avoid duplicating CRUD logic across UserCRUD and PersonCRUD by creating a generic base implementation that works with any entity.
Step 1: Define a Generic BaseDAO Interface
First, create an interface with standard CRUD operations, using generics to support any entity type:
package your.package.cruds; import java.util.List; public interface BaseDAO<T> { T findById(Long id); void save(T entity); void update(T entity); void delete(T entity); List<T> findAll(); }
Step 2: Implement the BaseDAO with JTA Support
Create a concrete implementation that uses a container-managed EntityManager (since you're using JTA, we'll leverage @PersistenceContext for injection):
package your.package.cruds.impl; import your.package.cruds.BaseDAO; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.persistence.TypedQuery; import java.util.List; public abstract class BaseDAOImpl<T> implements BaseDAO<T> { @PersistenceContext(unitName = "YourPersistenceUnitName") protected EntityManager em; private final Class<T> entityClass; // Constructor to pass the entity class (for generic querying) protected BaseDAOImpl(Class<T> entityClass) { this.entityClass = entityClass; } @Override public T findById(Long id) { return em.find(entityClass, id); } @Override public void save(T entity) { em.persist(entity); } @Override public void update(T entity) { em.merge(entity); } @Override public void delete(T entity) { em.remove(em.contains(entity) ? entity : em.merge(entity)); } @Override public List<T> findAll() { TypedQuery<T> query = em.createQuery("SELECT e FROM " + entityClass.getSimpleName() + " e", entityClass); return query.getResultList(); } }
Step 3: Extend the Base Class for Your Specific Entities
Now you can simplify UserCRUD and PersonCRUD by extending the base class—no need to rewrite basic CRUD logic:
// UserCRUD (local entity) package your.package.cruds; import your.package.cruds.impl.BaseDAOImpl; import your.package.entities.User; public class UserCRUD extends BaseDAOImpl<User> { public UserCRUD() { super(User.class); } // Add any User-specific methods here, e.g., findByUsername public User findByUsername(String username) { return em.createQuery("SELECT u FROM User u WHERE u.username = :username", User.class) .setParameter("username", username) .getSingleResult(); } }
// PersonCRUD (remote entity) package your.package.cruds; import your.remote.package.entities.Person; import your.package.cruds.impl.BaseDAOImpl; public class PersonCRUD extends BaseDAOImpl<Person> { public PersonCRUD() { super(Person.class); } // Add Person-specific methods here }
2. Handling Cross-Project Entities (Person from Remote Entities Module)
Since Person lives in a separate remote entities project, you need to ensure proper configuration and dependency setup:
Step 1: Configure Project Dependencies in Eclipse
- If you're using Maven: Add the remote entities module as a dependency in your local
crudsandservletsmodules'pom.xml:<dependency> <groupId>your.remote.group</groupId> <artifactId>remote-entities</artifactId> <version>1.0.0</version> <scope>compile</scope> </dependency> - If you're using plain Java projects: Right-click your local
cruds/servletsproject →Build Path→Add Projects→ Select the remote entities project.
Step 2: Update persistence.xml to Include Remote Entities
Your persistence.xml must explicitly list all entities (local and remote) that the persistence unit manages. Add the Person class to the <class> tags:
<persistence-unit name="YourPersistenceUnitName" transaction-type="JTA"> <!-- Local entity --> <class>your.package.entities.User</class> <!-- Remote entity --> <class>your.remote.package.entities.Person</class> <!-- Other JTA configuration (data source, etc.) --> <jta-data-source>java:jboss/datasources/YourDataSource</jta-data-source> <!-- ... --> </persistence-unit>
Note: If you prefer not to list every entity, you can set
<exclude-unlisted-classes>false</exclude-unlisted-classes>, but this is not recommended for production as it can include unintended classes.
Step 3: Ensure Entity Compatibility
- Make sure the remote
Personclass is properly annotated with JPA annotations (@Entity,@Id, etc.) and implementsSerializable(to avoid classloader issues across projects):package your.remote.package.entities; import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.io.Serializable; @Entity public class Person implements Serializable { @Id private Long id; private String name; // Getters, setters, constructors }
Step 4: Use Remote Entities in Servlets
In your _Index2 servlet, you can inject or instantiate PersonCRUD just like UserCRUD (ensure JTA transactions are active—use @Transactional if your container supports it, e.g., TomEE, WildFly):
package your.package.servlets; import your.package.cruds.PersonCRUD; import your.remote.package.entities.Person; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.transaction.Transactional; import java.io.IOException; @WebServlet("/_Index2") public class _Index2 extends HttpServlet { private PersonCRUD personCRUD = new PersonCRUD(); @Override @Transactional // Ensures JTA transaction wraps the operation protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Person person = new Person(); person.setName("John Doe"); personCRUD.save(person); response.getWriter().write("Person saved successfully!"); } }
Key Notes for JTA Compatibility
- Ensure your servlet container/application server supports JTA (e.g., TomEE, WildFly, GlassFish)—plain Tomcat does not include JTA out of the box.
- Use container-managed
EntityManager(via@PersistenceContext) instead of creating your own to align with JTA transaction management. - For transactional operations, use
@Transactionalannotation (or manualUserTransactionlookup if needed) to ensure CRUD operations run within a JTA transaction.
内容的提问来源于stack exchange,提问作者JayC667

