EntityManager不会持久化实体类?

时间:2014-10-02 17:54:25

标签: java mysql maven jpa wildfly

我正在尝试将JPA用于RESTful WebService的Java Web应用程序中的持久性。该程序通过EntityManager运行,持久化Entity类,被事务包围(开始和提交)。这笔交易虽然令人烦恼。当我检查MySQL数据库时,会创建必要的表,但不会在其中创建任何条目。怎么可能?代码有什么问题?

我的服务类:

@Stateless
public class ReportService {
    @PersistenceContext(unitName = "AbcPU") // default type is PersistenceContextType.TRANSACTION
    EntityManager em;

    public void saveDog() {
        System.out.println("BBBBB Start ReportService.saveDog();");
        Doggy doggy = new Doggy();
        doggy.setDogName("Wuffi");
        try {
            System.out.println("BBBBB Persist Success ReportService.saveDog();");
            em.getTransaction().begin();
            em.persist(doggy);
            em.flush();
            em.getTransaction().commit();
        } catch (Exception ex) {
            System.out.println("BBBBB Persist Fail ReportService.saveDog();");
            System.err.println("Error with em.persist(doggy): " + ex.getMessage());
        }
        System.out.println("BBBBB Stop ReportService.saveDog();");
    }
}

我的资源类:

@Path("report")
@Produces(MediaType.APPLICATION_JSON)
public class ReportResource {
    @EJB
    private ReportService rs;

    @GET
    public Response findReports() {
        final List<Report> reports = rs.findAllReports();

        System.out.println("AAAAA Start rs.saveDog();");
        rs.saveDog();
        System.out.println("AAAAA Stop rs.saveDog();");

        return Response.ok(new GenericEntity<List<Report>>(reports) {})
                       .build();
    }
}

我的实体类:

@Entity
public class Doggy implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotNull
    private String dogName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDogName() {
        return dogName;
    }

    public void setDogName(String dogName) {
        this.dogName = dogName;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Doggy)) {
            return false;
        }
        Doggy other = (Doggy) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.glasses.pandora.domain.Doggy[ id=" + id + " ]";
    }
}

我的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="AbcPU" transaction-type="JTA">
    <jta-data-source>java:/jdbc/abc</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
    </properties>
  </persistence-unit>
</persistence>

pom.xml中的My Maven依赖项:

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.32</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.1.Final</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>unknown.binary</groupId>
        <artifactId>hibernate-jpamodelgen-4.3.1.Final</artifactId>
        <version>SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

运行后我的控制台输出:

01:58:54,158 INFO  [stdout] (default task-23) AAAAA Start rs.saveDog();
01:58:54,160 INFO  [stdout] (default task-23) BBBBB Start ReportService.saveDog();
01:58:54,160 INFO  [stdout] (default task-23) BBBBB Persist Success ReportService.saveDog();
01:58:54,160 INFO  [stdout] (default task-23) BBBBB Persist Fail ReportService.saveDog();
01:58:54,161 ERROR [stderr] (default task-23) Error with em.persist(doggy): A JTA EntityManager cannot use getTransaction()
01:58:54,161 INFO  [stdout] (default task-23) BBBBB Stop ReportService.saveDog();
01:58:54,162 INFO  [stdout] (default task-23) AAAAA Stop rs.saveDog();

mysql show tables:

mysql> show tables;
+--------------------+
| Tables_in_abc      |
+--------------------+
| Doggy              |
| hibernate_sequence |
+--------------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM Doggy;
Empty set (0.00 sec)

mysql>

4 个答案:

答案 0 :(得分:1)

检查服务器日志以查看您的应用程序是否确实使用了MySQL数据源或嵌入式默认H2数据源。

您的persistence.xml不包含<jta-data-source>,因此我要说正在使用默认数据源。

请参阅有关Datasource Configuration的Wiki文章。

答案 1 :(得分:1)

有一些问题。 hwellmann提到的第一个是你没有指定数据源。 JTA要求使用与JTA事务关联的连接。

第二个问题是你似乎没有在一个事务中包装saveDog方法。持久调用只会向上下文注册实体;它仅在提交关联事务时插入数据库,或者调用EntityManager.flush()。如果在save方法中调用em.flush,这将验证您的EntityManager是否与事务正确关联,并且插入是否成功。

答案 2 :(得分:1)

查看错误 - Error with em.persist(doggy): A JTA EntityManager cannot use getTransaction()。 EJB正在自动处理事务 - 从ReportService em.getTransaction().begin()em.flush();em.getTransaction().commit();

中删除以下内容

你的方法应该是这样的:

public void saveDog() {
        System.out.println("BBBBB Start ReportService.saveDog();");
        Doggy doggy = new Doggy();
        doggy.setDogName("Wuffi");
        try {
            System.out.println("BBBBB Persist Success ReportService.saveDog();");
            em.persist(doggy);
        } catch (Exception ex) {
            System.out.println("BBBBB Persist Fail ReportService.saveDog();");
            System.err.println("Error with em.persist(doggy): " + ex.getMessage());
        }
        System.out.println("BBBBB Stop ReportService.saveDog();");
    }  

答案 3 :(得分:-2)

我很确定你需要查找你的持久化上下文并从中分配实体管理器。

@Dependent
@Stateful
public class ReportService {
    @PersistenceContext(name = "persistence/AbcPU", unitName = "AbcPU")

    public abstract EntityManager getEntityManager() {
       EntityManager em = null;
       try {
          Context envCtx = InitialContext.doLookup("java:comp/env");
          em = (EntityManager) envCtx.lookup("persistence/AbcPU");
       } catch (NamingException ne) {
          //Handle Exception
       }
       return em;
    }

    public void saveDog() {
        System.out.println("BBBBB Start ReportService.saveDog();");
        Doggy doggy = new Doggy();
        doggy.setDogName("Wuffi");
        try {
            System.out.println("BBBBB Persist Success ReportService.saveDog();");
            getEntityManager().persist(doggy);
        } catch (Exception ex) {
            System.out.println("BBBBB Persist Fail ReportService.saveDog();");
            System.err.println("Error with em.persist(doggy): " + ex.getMessage());
        }
        System.out.println("BBBBB Stop ReportService.saveDog();");
    }
}