如何使用hibernate设置UserTransaction

时间:2017-07-31 19:32:48

标签: java mysql hibernate wildfly jta

我有一个用于管理用户信息的mySQL数据库,我正在为mySQL数据库使用JTA数据源,这是persistence.xml的样子:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
   <persistence-unit name="SensorCloudPU" transaction-type="JTA">
      <jta-data-source>java:/SensorCloudPU</jta-data-source>
<!--      <non-jta-data-source>java:/SensorCloudPU</non-jta-data-source> -->
      <class>com.sensorhound.common.domain.impl.AnomalousInfo</class>
      <class>com.sensorhound.common.domain.impl.Code</class>
      <class>com.sensorhound.common.domain.impl.Device</class>
      <class>com.sensorhound.common.domain.impl.Executable</class>
      <class>com.sensorhound.common.domain.impl.Group</class>
      <class>com.sensorhound.common.domain.impl.GroupAlert</class>
      <class>com.sensorhound.common.domain.impl.GroupRule</class>
      <class>com.sensorhound.common.domain.impl.GroupRuleDefinition</class>
      <class>com.sensorhound.common.domain.impl.GroupRuleStatus</class>
      <class>com.sensorhound.common.domain.impl.Node</class>
      <class>com.sensorhound.common.domain.impl.NodeAlert</class>
      <class>com.sensorhound.common.domain.impl.NodeRule</class>
      <class>com.sensorhound.common.domain.impl.NodeRuleDefinition</class>
      <class>com.sensorhound.common.domain.impl.Organization</class>
      <class>com.sensorhound.common.domain.impl.PastGroupStatus</class>
      <class>com.sensorhound.common.domain.impl.Trace</class>
      <class>com.sensorhound.common.domain.impl.TrainingSession</class>
      <class>com.sensorhound.common.domain.impl.User</class>
      <class>com.sensorhound.common.domain.impl.Role</class>
      <exclude-unlisted-classes>true</exclude-unlisted-classes>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
         <property name="hibernate.show_sql" value = "false" />
         <property name="hibernate.connection.autocommit" value="true" />
         <property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
         <property name="transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
         <property name="jta.UserTransaction" value="java:jboss/UserTransaction"/>
      </properties>
   </persistence-unit>
</persistence>

我有一个这样的终点:

@Path("/delete")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public Response deleteUser(@FormParam("organization_id") Integer organizationId,
      @FormParam("username") String username) throws JsonProcessingException, NotSupportedException,
      SystemException, SecurityException, IllegalStateException, RollbackException,
      HeuristicMixedException, HeuristicRollbackException, NamingException {
    Organization org = organizationDAO.getByOrganizationId(organizationId);
    userDao.deleteUserByUserNameAndOrganization(username, org);
    return Response.status(Response.Status.OK).build();
  }

DAO是这样的:

public class userDAO {
  @PersistenceContext(unitName = "SensorCloudPU")
  protected EntityManager em;

  @Resource
  protected UserTransaction utx;

  public void deleteUserByUserNameAndOrganization(String userName, Organization org)
          throws NotSupportedException, SystemException, SecurityException, IllegalStateException,
          RollbackException, HeuristicMixedException, HeuristicRollbackException {
        Query q = this.em.createNamedQuery(User.Q_GET_BY_USERNAME_AND_ORGANIZATION);
        q.setParameter("organization", org);
        q.setParameter("user_name", userName);
        User u = this.executeQueryForSingleResult(q);
        if (u == null) {
          return;
        }
        utx.begin();
        this.em.remove(u);
        utx.commit();
      }
}

但每当我加载页面并尝试从数据库中删除时,我都会收到此错误:

注入的资源查找失败:java:jboss / UserTransaction]

UserTransaction [根异常是java.lang.IllegalStateException:WFLYEJB0137:只允许使用bean管理的事务划分的会话和消息驱动Bean访问UserTransaction]

2 个答案:

答案 0 :(得分:1)

除非添加@TransactionManagement(BEAN),否则不能在EJB中使用UserTransaction

TransactionManagement的作用是

指定会话Bean或消息驱动Bean是否具有容器管理事务或Bean管理事务。如果未使用此批注,则假定bean具有容器管理的事务管理。

@TransactionManagement(BEAN)
public class userDAO {

答案 1 :(得分:0)

由于您主要关注事务管理,我建议您将DAO转换为EJB。它只需要一行:

@Stateless
public class userDAO {

    @PersistenceContext(unitName = "SensorCloudPU")
    protected EntityManager em;

    public void deleteUserByUserNameAndOrganization(String userName, Organization org) {
        Query q = this.em.createNamedQuery(User.Q_GET_BY_USERNAME_AND_ORGANIZATION);
        q.setParameter("organization", org);
        q.setParameter("user_name", userName);
        User u = this.executeQueryForSingleResult(q);
        if (u != null) {
            this.em.remove(u);
        }
    }
}

你可以看到它显着简化了事情。 EJB免费为您提供JTA事务划分(如果需要,还可以回滚)。

即使您正在构建仅限WAR的部署,这也会有效。

如果需要,您还可以将@Stateless添加到JAX-RS端点。至少你会得到比你原本拥有的更多的监控。

相关问题