I've read many of the other examples, but cannot seem to persist my data with hibernate.
I have code here that creates the objects:
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;
}
}
Then, I have the object class itself:
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;
}
And finally my config page:
<!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>
When I run everything, this is what I get spit back from the process:
[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
It looks like above the object is properly created, but I am really struggling on the persistence side. Any help would be greatly appreciated.
Okay, unfortunately, my post must not have gotten enough attention here, but I have done tons of research around this area now and thought I would share what I found.
First, I changed to SQL instead of using hibernates native database. This sped things up 10 fold. I understand it may not be the best solution for all applications, but for smaller or non-essential applications, its the easiest.
Below my Hibernate config file:
<!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>
Note that the port will usually be 3306 if you are running locally. If that is your goal, make sure to set up your MySQL database as such (and look for the port it will be listening on). You will have to install the JDBC jar. The easiest way is if you have homebrew. Note it is a two step installation: https://github.com/gbeine/homebrew-java
brew tap gbeine/homebrew-java
brew install mysql-connector-java
Below your main configuration, you have to tell Hibernate what your classes are. This is the mapping class section. I have seen a million implementations of this with package mapping, etc. Again, for a simple app, this is easiest.
Once you have mapped your class in the Hibernate config file, go back to your .java class to structure it in a way Hibernate will associate it properly with your MySQL tables.
@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;
When you declare each variable, you need to assure that you have the correct data type. You can see here that I have incorrectly (on purpose) declared progress an int when it should be a double.
Note that I have declared these variables as columns and the name of the column in the DB. This is essential and you will have many headaches without this.
Finally, when you go to save your data, I found there are tons of stackoverflow descriptions for forms, but none for backend initiated DB saves. So, I have included that code below, too:
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));
}
}
Basically, you have to start a session with @Inject. Then, as this is a WS that processes URL parameters, I use @SetupRender to start the method upon page render. Many times, people put the @CommitAfter after this entire method with an OnSuccess method, but for java initiated sessions, this does not work. So for these, I put it directly after the SetupRender to make sure that all the session saves/edits/deletes I perform during the method are committed afterwards. Without this, your program will quietly fail. Nothing will jump out at you and your data will not be saved.
I apologize as I am a bit of a newb at development so I may not have described everything here optimally, but hope it can help someone down the road.