使用Hibernate问题保留Tapestry中的数据

时间:2015-07-23 00:46:41

标签: java database hibernate tapestry

我已经阅读了许多其他示例,但似乎无法使用hibernate保留我的数据。

我这里有代码创建对象:

package com.example.leaderboardApp.pages;

import com.example.leaderboardApp.utility.Competitor;
import org.apache.tapestry5.annotations.RequestParameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.annotations.ActivationRequestParameter;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;



public class Ws {
    @ActivationRequestParameter("hipchat_id") private int hipchat_id;
    @ActivationRequestParameter("name") private String name;
    @ActivationRequestParameter("dips") private int dips;

    @Property
    private Competitor competitor;

    @Inject
    private Session session;

    @SetupRender
    void appUpdate() {
        competitor = new Competitor(hipchat_id, name);
        competitor.addReps(dips);
        System.out.println(competitor);
    }

    @CommitAfter
    Object onSuccess() {
        session.persist(competitor);
        return hipchat_id;
    }
}

然后,我有对象类本身:

package com.example.leaderboardApp.utility;

import java.util.ArrayList;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.apache.tapestry5.beaneditor.NonVisual;
import org.apache.tapestry5.beaneditor.Validate;

import com.example.leaderboardApp.pages.Index;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;


@Entity()
public class Competitor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @NonVisual
    public int hipchat_id;

    @Validate("required")
    private String name;

    private int score;

    private int goal = 14000;

    private int progress = score/goal;

    public Competitor(int hipchat_id, String name) {
        this.hipchat_id = hipchat_id;
        this.name = name;
    }


    public String getName() {
        return this.name;
    }

    public void addReps(int repetitions) {
        this.score += repetitions;
    }

最后是我的配置页面:

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:./target/work/leaderboardApp;shutdown=true</property>
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="hibernate.connection.username"></property>
        <property name="hibernate.connection.password"></property>
        <property name="hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <mapping package="com.example.leaderboardApp.utility.Competitor" />
    </session-factory>
</hibernate-configuration>

当我运行所有内容时,这就是我从流程中吐出的内容:

 [INFO] Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] common.Version Hibernate Commons Annotations 3.2.0.Final
[INFO] cfg.Environment Hibernate 3.6.0.Final
[INFO] cfg.Environment hibernate.properties not found
[INFO] cfg.Environment Bytecode provider name : javassist
[INFO] cfg.Environment using JDK 1.4 java.sql.Timestamp handling
[INFO] cfg.Configuration configuring from resource: /hibernate.cfg.xml
[INFO] cfg.Configuration Configuration resource: /hibernate.cfg.xml
[WARN] util.DTDEntityResolver recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
[INFO] cfg.Configuration Mapping package com.example.leaderboardApp.utility.Competitor
[WARN] cfg.AnnotationBinder Package not found or wo package-info.java: com.example.leaderboardApp.utility.Competitor
[INFO] cfg.Configuration Configured SessionFactory: null
[INFO] cfg.Configuration Mapping package com.example.leaderboardApp.entities
[WARN] cfg.AnnotationBinder Package not found or wo package-info.java: com.example.leaderboardApp.entities
[INFO] cfg.Configuration Hibernate Validator not found: ignoring
[INFO] search.HibernateSearchEventListenerRegister Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
[INFO] connection.DriverManagerConnectionProvider Using Hibernate built-in connection pool (not for production use!)
[INFO] connection.DriverManagerConnectionProvider Hibernate connection pool size: 20
[INFO] connection.DriverManagerConnectionProvider autocommit mode: false
[INFO] connection.DriverManagerConnectionProvider using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:./target/work/leaderboardApp;shutdown=true
[INFO] connection.DriverManagerConnectionProvider connection properties: {user=, password=****}
[INFO] cfg.SettingsFactory Database ->
       name : HSQL Database Engine
    version : 2.3.2
      major : 2
      minor : 3
[INFO] cfg.SettingsFactory Driver ->
       name : HSQL Database Engine Driver
    version : 2.3.2
      major : 2
      minor : 3
[INFO] dialect.Dialect Using dialect: org.hibernate.dialect.HSQLDialect
[INFO] transaction.TransactionFactoryFactory Using default transaction strategy (direct JDBC transactions)
[INFO] transaction.TransactionManagerLookupFactory No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
[INFO] cfg.SettingsFactory Automatic flush during beforeCompletion(): disabled
[INFO] cfg.SettingsFactory Automatic session close at end of transaction: disabled
[INFO] cfg.SettingsFactory JDBC batch size: 15
[INFO] cfg.SettingsFactory JDBC batch updates for versioned data: disabled
[INFO] cfg.SettingsFactory Scrollable result sets: enabled
[INFO] cfg.SettingsFactory JDBC3 getGeneratedKeys(): enabled
[INFO] cfg.SettingsFactory Connection release mode: auto
[INFO] cfg.SettingsFactory Default batch fetch size: 1
[INFO] cfg.SettingsFactory Generate SQL with comments: disabled
[INFO] cfg.SettingsFactory Order SQL updates by primary key: disabled
[INFO] cfg.SettingsFactory Order SQL inserts for batching: disabled
[INFO] cfg.SettingsFactory Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
[INFO] ast.ASTQueryTranslatorFactory Using ASTQueryTranslatorFactory
[INFO] cfg.SettingsFactory Query language substitutions: {}
[INFO] cfg.SettingsFactory JPA-QL strict compliance: disabled
[INFO] cfg.SettingsFactory Second-level cache: enabled
[INFO] cfg.SettingsFactory Query cache: disabled
[INFO] cfg.SettingsFactory Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
[INFO] cfg.SettingsFactory Optimize cache for minimal puts: disabled
[INFO] cfg.SettingsFactory Structured second-level cache entries: disabled
[INFO] cfg.SettingsFactory Echoing all SQL to stdout
[INFO] cfg.SettingsFactory Statistics: disabled
[INFO] cfg.SettingsFactory Deleted entity synthetic identifier rollback: disabled
[INFO] cfg.SettingsFactory Default entity-mode: pojo
[INFO] cfg.SettingsFactory Named query checking : enabled
[INFO] cfg.SettingsFactory Check Nullability in Core (should be disabled when Bean Validation is on): enabled
[INFO] impl.SessionFactoryImpl building session factory
[INFO] impl.SessionFactoryObjectFactory Not binding factory to JNDI, no JNDI name configured
[INFO] hbm2ddl.SchemaUpdate Running hbm2ddl schema update
[INFO] hbm2ddl.SchemaUpdate fetching database metadata
[INFO] hbm2ddl.SchemaUpdate updating schema
[INFO] hbm2ddl.SchemaUpdate schema update complete
[INFO] HibernateCoreModule.HibernateSessionSource Hibernate startup: 122 ms to configure, 371 ms overall.
[INFO] HibernateCoreModule.HibernateSessionSource Configured Hibernate entities: (none)
com.example.leaderboardApp.utility.Competitor@3d03f309
[INFO] AppModule.TimingFilter Request time: 954 ms

看起来上面的对象是正确创建的,但我真的在持久性方面苦苦挣扎。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

好的,不幸的是,我的帖子一定不会引起足够的关注,但我现在已经围绕这个领域进行了大量的研究,并认为我会分享我发现的内容。

首先,我更改为SQL而不是使用hibernates本机数据库。这加快了10倍。我知道它可能不是所有应用程序的最佳解决方案,但对于较小或非必要的应用程序,它是最简单的。

在我的Hibernate配置文件下面:

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/leaderboardApp</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <property name="hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <mapping class="com.example.leaderboardApp.utility.Competitor"/>
        <mapping class="com.example.leaderboardApp.utility.Record"/>
    </session-factory>
</hibernate-configuration>

请注意,如果您在本地运行,端口通常为3306。如果这是您的目标,请确保设置MySQL数据库(并查找它将监听的端口)。您将不得不安装JDBC jar。最简单的方法是如果你有自制软件。请注意,这是一个两步安装:https://github.com/gbeine/homebrew-java

brew tap gbeine/homebrew-java
brew install mysql-connector-java

在主要配置下面,你必须告诉Hibernate你的课程是什么。这是映射类部分。我已经看到了包含映射等的一百万个实现。再次,对于一个简单的应用程序,这是最简单的。

一旦你在Hibernate配置文件中映射了你的类,回到你的.java类来构建它,Hibernate会将它与你的MySQL表正确地关联起来。

@Entity
@Table(name="competitors")
public class Competitor {
    @Id
    @Column(name="hipchat_id", unique=true, nullable=false)
    public int hipchat_id;

    @Column(name="name")
    @Validate("required")
    private String name;

    @Column(name="score")
    private int score;

    @Column(name="goal")
    private int goal = 14000;

    @Column(name="progress")
    private int progress = score/goal;

声明每个变量时,需要确保拥有正确的数据类型。你可以在这里看到我错误地(故意)声明进度是一个int,它应该是一个双。

请注意,我已将这些变量声明为列以及DB中列的名称。这是必不可少的,没有这个你会有很多麻烦。

最后,当您去保存数据时,我发现表单有大量的stackoverflow描述,但后端启动的DB保存没有。所以,我也在下面包含了这些代码:

public class Ws {
    @ActivationRequestParameter("hipchat_id") private int hipchat_id;
    @ActivationRequestParameter("name") private String name;
    @ActivationRequestParameter("dips") private int dips;

    @Property
    private Competitor competitor;

    @Inject
    private Session session;

    @SetupRender
    @CommitAfter
    void appUpdate() {
        session.saveOrUpdate(new Competitor(hipchat_id, name, dips));
        session.save(new Record(hipchat_id, dips));
    }

}

基本上,您必须使用@Inject启动会话。然后,由于这是一个处理URL参数的WS,我使用@SetupRender在页面渲染时启动方法。很多时候,人们使用OnSuccess方法将整个方法放在@CommitAfter之后,但对于java启动的会话,这不起作用。因此,对于这些,我将它直接放在SetupRender之后,以确保我在方法之后执行的所有会话保存/编辑/删除都是在之后提交的。没有这个,你的程序将悄然失败。什么都不会突然冒出来,你的数据将无法保存。

我道歉,因为我在开发方面有点新意,所以我可能没有最好地描述这里的一切,但希望它可以帮助有人在路上。