【问题标题】:Persisting entities持久实体
【发布时间】:2013-05-13 09:45:28
【问题描述】:

我刚刚开始进行 EJB 开发,所以我创建了一个包含以下三个项目的测试系统:

其实HelloWorldBeanRemote这个接口也确实存在于EJBTest项目中。我还没有找到一种方法可以从其他项目中导入它而不会出现运行时异常。

EJBTestInterfaces 是一个纯 java 项目,仅包含远程接口。 EJBTest 包含程序逻辑。 HelloWorldBean 是一个会话 bean。它的构造函数将created 字段设置为当前时间。在sayHello() 方法中,它使用注入的PersistenceManager 来检索id 为0 的TestEntity(如果不存在则创建它),递增“hit”变量并返回它:

@PersistenceContext(name="manager1") 
private EntityManager em;

@Override
public String sayHello() {
    String info;
    if (em == null)
        info = "Entity Manager is null";
    else {
        TestEntity entity;
        try {
            entity = em.find(TestEntity.class, 0);
            entity.setHits(entity.getHits() + 1);
            em.merge(entity);
            info = "Hit entity " + entity.getHits() + " times.";
        } catch(Exception x) {
            entity = new TestEntity();
            em.persist(entity);
            info = "Never used entity bean before.";
        } 
    }
    return "Hello! I was created at " + created.toString() + "<br>" + info;
}

持久化单元在persistence.xml中定义如下:

<persistence>
   <persistence-unit name="manager1">
       <jta-data-source>java:jboss/datasources/AppointmentDS</jta-data-source>
       <jar-file>../EJBTest.jar</jar-file>
       <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                  <!-- also tried value="validate" -->
       </properties>
   </persistence-unit>
</persistence>

它使用standalone.xml中定义的嵌入式数据库:

<datasource jndi-name="java:jboss/datasources/AppointmentDS" pool-name="AppointmentDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:h2:file:[path to file]</connection-url>
    <driver>h2</driver>
    <security>
        <user-name>sa</user-name>
        <password>sa</password>
    </security>
</datasource>

servlet基本输出sayHello()的返回值:

doGet(...) {
    //get initial context ...

    bean = (HelloWorldBeanRemote)initialContext.lookup(name);
    output.write(bean.sayHello());
}

如果我现在通过 Web 浏览器调用 servlet,我会得到预期的输出:创建日期和“以前从未使用过实体 bean”。如果我刷新页面,创建日期不会改变,但点击计数会增加。我可以在不更改此行为的情况下重新启动 servlet 项目。命中计数稳步增加。

但是,如果我重新启动 EJB 项目,一切都会重置为零。这是创建日期的预期行为,但应从数据库中读取命中计数。但事实并非如此。

我可以在指定目录中看到创建的数据库文件,它们似乎包含数据(我只是在文本编辑器中打开了文件)。

我应该像以前那样使用会话 bean 吗?我不确定是否必须在请求后关闭 bean(以便事务可以提交)。

如何让 EJB 项目从数据库文件中读取持久化数据?

【问题讨论】:

    标签: eclipse jpa ejb-3.0 jboss7.x


    【解决方案1】:

    您需要将hibernate.hbm2ddl.auto 的值从create-drop 更改为validate 或其他一些值。 create-drop 将在 SessionFactory 关闭时删除整个架构,并在打开时重新创建它。

    【讨论】:

    • 不只是架构改变的情况吗?将值更改为 validate 不会改变行为。
    • 不,我认为每次关闭服务器时都会重新创建它
    • 如果您在应用程序之外查询数据库,它的值是否正确?
    • 这很有趣。当我在文本编辑器中打开文件时,我可以看到命令UCREATE CACHED TABLE PUBLIC.TEST(ID INTEGER NOT NULL, HITS INTEGER NOT NULL),但是当我在 Eclipse 中打开数据库时,没有表 Public.Test。 (我将实体的表设置为“测试”)
    • 会不会是事务从来没有提交过?
    【解决方案2】:

    可能是在您重新启动 EJB 项目后,即当最后一个连接消失时,H2 会重置 DB。 停止您的 EJB 项目并连接到数据库以查看预期的数据是否仍然存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-18
      • 2015-11-15
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多