Hibernate 错误:事务未激活
这是导致错误的源代码:Hibernate 错误:事务未激活,hibernate,jpa,servlets,Hibernate,Jpa,Servlets,这是导致错误的源代码: @Override @Transactional @TransactionAttribute(TransactionAttributeType.REQUIRED) public Object queryObject(String query) throws Exception { Object o = null; EntityTransaction tr = em.getTransaction(); try { if (!tr.i
@Override
@Transactional
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Object queryObject(String query) throws Exception {
Object o = null;
EntityTransaction tr = em.getTransaction();
try {
if (!tr.isActive()) {
tr.begin();
}
List<Object> objectsList = em.createQuery(query).getResultList();
if (!objectsList.isEmpty()) {
o = objectsList.get(0);
}
em.flush();
em.clear();
em.close();
tr.commit();
} catch (Exception e) {
tr.rollback();
System.out.println("" + e.getMessage());
}
return o;
}
@覆盖
@交易的
@TransactionAttribute(TransactionAttributeType.REQUIRED)
公共对象queryObject(字符串查询)引发异常{
对象o=null;
EntityTransaction tr=em.getTransaction();
试一试{
如果(!tr.isActive()){
tr.begin();
}
List objectsList=em.createQuery(query.getResultList();
如果(!objectsList.isEmpty()){
o=objectsList.get(0);
}
em.flush();
em.clear();
em.close();
tr.commit();
}捕获(例外e){
tr.rollback();
System.out.println(“+e.getMessage());
}
返回o;
}
这是调用方法的指令:
UserAccount UserAccount=(UserAccount)accountDao.queryObject(“从UserAccount中选择u.identifier、u.email、u.password作为u,其中identifier=“+account.getIdentifier()+”和password=“+account.getPassword()) 您使用的是容器管理的事务-您不需要自己做这件事 您的代码可以折叠为:
@Override
@Transactional
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Object queryObject(String query) throws PersistenceException {
try {
return em.createQuery(query).getSingleResult();
} catch (NonUniqueResultException e) {
// too many results
return null;
} catch (NoResultException e) {
// not enough results
return null;
}
}
但是
按如下方式组合查询:
"select u.identifier,u.email,u.password from UserAccount as u where identifier="
+ account.getIdentifier() + " and password=" + account.getPassword())
可以导致
JPA类有一组setParameter
方法,您必须使用这些方法来避免这种情况
因此,编写特定的查询方法通常比您在这里尝试的通用方法更容易。您是否检查了非活动事务?如果您使用的是@Transactional
,为什么要手动管理事务
我还想向您展示如何更好地编写dao(查看自动转换为UserAccount.class
以及使用参数避免注入):
此代码是手工编写的,因此可能包含一些错误。请添加您遇到的错误。为什么要在提交其事务之前关闭EntityManager?!如果你得到一个例外,你说它发生在哪一行谢谢你,这对我很有帮助。使用您的源代码,我终于找到了问题的解决方案。
@Stateless
@Transactional
public class UserAccountDao {
private static final String SELECT_USERACCOUNT_BY_IDENTIFIER_AND_PASSWORD = "select ua from UserAccount ua where ua.identifier = :identifier and ua.password = :password";
@PersistenceContext
EntityManager em;
public UserAccount selectUserAccountByIdentifierAndPAssword(final String identifier, final String password) {
List<UserAccount> userAccounts = em.createQuery(SELECT_USERACCOUNT_BY_IDENTIFIER_AND_PASSWORD, UserAccount.class)
.setParameter("identifier", identifier)
.setParameter("password", password)
.getResultList();
return userAccounts == null || userAccounts.isEmpty() ? null : userAccounts.get(0);
}
}
UserAccount userAccount = uadao.selectUserAccountByIdentifierAndPAssword(account.getIdentifier(), account.getPassword());
if (userAccount == null) {
// manage error
}