我正在尝试使用JPA,CDI(OpenWebBeans + Deltaspike JPA模块),JSF构建应用程序。我使用部署在Tomcat上的CDI的方式与我习惯使用Spring框架的方式相同。我有这样的名为GenericDAOImpl的DAO(前几行):
public abstract class GenericDaoJpa<T> implements GenericDao<T> {
private static final Log logger = LogFactory.getLog(GenericDaoJpa.class);
@Inject
protected EntityManager entityManager;
private Class<T> type;
使用DeltaSpike JPA modulehttp://deltaspike.apache.org/jpa.html注入EntityManager。这个GenericDao然后由服务类使用的具体DAO(UserDao等...)继承。
例如UserServiceImpl:
public class UserServiceImpl implements UserService {
private static final Log logger = LogFactory.getLog(UserServiceImpl.class);
@Inject
private UserDao userDao;
@Transactional
public void saveUser(UserDto user) throws UserServiceException {
try {
User u = new User(user);
userDao.create(u);
} catch (Exception e) {
logger.error("Error while creating user.", e);
throw new UserServiceException("Error while creating user.");
}
}
}
以这种方式使用CDI DAO和Service类都具有Dependent范围,而不像spring那样它们是singleton。因此,每个客户端都会注入新实例。 我应该将DAO和Service类的范围更改为ApplicationScope吗?但是根据规范,我必须使所有被注入的类都可序列化。在Dao类的情况下,这可能是一个问题,EntityManager应该被标记为瞬态?甲
我很乐意提出任何建议。
答案 0 :(得分:5)
@ApplicationScoped
与Serializable
无关,它们始终存在,永远不会持久存在于磁盘上。由于HTTP会话对象的行为,@SessionScoped
将需要序列化。
我建议使用范围,因为保留所有依赖项将导致内存泄漏(删除@Dependent
对象时永远不会清楚)。如果您的应用程序是无状态的,则可以使用@RequestScoped
。 @ApplicationScoped
您需要考虑多个客户端将连接到您的实例。