Hibernate version: 2.1.7
Database you are using: AS400
I have all my many-to-many relationships setup using two one-to-many's, with an association table, also I'm using surragote keys throughout my database.
below are the classes and mappings for one of these relationships.
A User has many goals and a Goal can be associated with many users
I'm running all this on Tomcat 5.0.28 using just jsp's and servlets
And I use the following Listener to get a HibernateSession:
Code:
package us.wi.k12.madison.plp.listeners;
import java.util.*;
import javax.servlet.*;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.Configuration;
import org.apache.log4j.*;
/**
* Description of the Class
*
* @author Zeb Wollner
* @since March 9, 2005
*/
public class HibernateManager implements ServletContextListener {
private Logger logger = Logger.getLogger(getClass());
private static SessionFactory sessionFactory;
private static String sessionFile;
/**
* @param event Description of the Parameter
*/
public void contextInitialized(ServletContextEvent event) {
ServletContext context = event.getServletContext();
sessionFile = context.getInitParameter("sessionConfigFile");
logger.debug("Hibernate session file: " + sessionFile);
logger.info("Starting to configure Hibernate session factory");
try {
Configuration config = new Configuration();
config.configure(sessionFile);
sessionFactory = config.buildSessionFactory();
logger.info("Hibernate session factory configured");
} catch (net.sf.hibernate.HibernateException he) {
logger.error("Could not build the Hibernate session factory", he);
}
}
/**
* Description of the Method
*
* @param event Description of the Parameter
*/
public void contextDestroyed(ServletContextEvent event) {
logger.info("SessionFactory is being shutdown");
try {
if (sessionFactory != null) {
sessionFactory.close();
}
} catch (net.sf.hibernate.HibernateException he) {
logger.error("Could not close the Hibernate session factory", he);
}
}
/**
* Gets the sessionFactory attribute of the HibernateManager object
*
* @return The sessionFactory value
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
then at the begining of every servlet that I need to access the database I do something simmliar to the following:
Code:
try {
//Get the session factory from the Hibernate listener
sessionFactory = HibernateManager.getSessionFactory();
//Open a Hibernate session
hibSession = sessionFactory.openSession();
//Begin a Hibernate transaction
tx = hibSession.beginTransaction();
//CRUD here
} catch (net.sf.hibernate.HibernateException he) {
logger.error("Error running Hibernate query", he);
} finally {
try {
if (tx != null) {
//Commit the transaction
tx.commit();
}
if (hibSession != null) {
//Close the Hibernate session
hibSession.close();
}
} catch (net.sf.hibernate.HibernateException he) {
logger.error("Error closing Hibernate query", he);
}
}
Mapping Classes: User Table
Code:
package us.wi.k12.madison.plp.model;
import java.io.*;
import java.util.*;
import java.util.List;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import org.apache.commons.lang.builder.*;
import org.apache.log4j.*;
/**
* Description of the Class
*
* @author Zeb Wollner
* @since February 28, 2005
* @hibernate.class schema="PLPTEST" table="PLPUSER"
* @hibernate.query name="us.wi.k12.madison.plp.model.readAllUsers"
* query="from PlpUser as PlpUser"
* @hibernate.query name="us.wi.k12.madison.plp.model.readUserByUserNumber"
* query="from PlpUser as PlpUser where PlpUser.userNumber = :userNumber"
*/
public class PlpUser implements Serializable {
private Logger logger = Logger.getLogger(getClass());
private Integer userId;
private String role;
private Integer userNumber;
private String firstName;
private String lastName;
private String password;
private String firstTime;
private Set studentLearningStyleGoal;
/**
* Returns the value of studentLearningStyleGoal.
*
* @return The learningStyleGoal value
* @hibernate.set inverse="true" cascade="save-update" lazy="false"
* @hibernate.collection-key column="USER_ID"
* @hibernate.collection-one-to-many
* class="us.wi.k12.madison.plp.model.StudentLearningStyleGoal"
*/
public Set getStudentLearningStyleGoal() {
return studentLearningStyleGoal;
}
/**
* Adds a feature to the LearningStyleGoal attribute of the PlpUser object
*
* @param slsl The feature to be added to the LearningStyleGoal attribute
*/
public void addLearningStyleGoal(StudentLearningStyleGoal slsg) {
slsg.setUser(this);
studentLearningStyleGoal.add(slsg);
}
/**
* Sets the value of studentLearningStyleGoal.
*
* @param studentLearningStyleGoal The value to assign
* studentLearningStyleGoal.
*/
public void setStudentLearningStyleGoal(Set studentLearningStyleGoal) {
this.studentLearningStyleGoal = studentLearningStyleGoal;
}
/**
* Returns the value of userId.
*
* @return The userId value
* @hibernate.id column="USER_ID" generator-class="hilo"
* @hibernate.generator-param name = "table" value = "PLPTEST.HILO"
* @hibernate.generator-param name = "column" value = "NEXT_HI"
*/
public Integer getUserId() {
return userId;
}
/**
* Sets the value of userId.
*
* @param userId The value to assign userId.
*/
public void setUserId(Integer userId) {
this.userId = userId;
}
/**
* Returns the value of role.
*
* @return The role value
* @hibernate.property column="ROLE"
*/
public String getRole() {
return role;
}
/**
* Sets the value of role.
*
* @param role The value to assign role.
*/
public void setRole(String role) {
this.role = role;
}
/**
* Returns the value of userNumber.
*
* @return The userNumber value
* @hibernate.property column="USER_NUMBER"
*/
public Integer getUserNumber() {
return userNumber;
}
/**
* Sets the value of userNumber.
*
* @param userNumber The value to assign userNumber.
*/
public void setUserNumber(Integer userNumber) {
this.userNumber = userNumber;
}
/**
* Returns the value of firstName.
*
* @return The firstName value
* @hibernate.property column="FIRST_NAME"
*/
public String getFirstName() {
return firstName;
}
/**
* Sets the value of firstName.
*
* @param firstName The value to assign firstName.
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Returns the value of lastName.
*
* @return The lastName value
* @hibernate.property column="LAST_NAME"
*/
public String getLastName() {
return lastName;
}
/**
* Sets the value of lastName.
*
* @param lastName The value to assign lastName.
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Returns the value of password.
*
* @return The password value
* @hibernate.property column="PASSWORD"
*/
public String getPassword() {
return password;
}
/**
* Sets the value of password.
*
* @param password The value to assign password.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Returns the value of firstTime.
*
* @return The firstTime value
* @hibernate.property column="FIRST_LOG_IN"
*/
public String getFirstTime() {
return firstTime;
}
/**
* Sets the value of firstTime.
*
* @param firstTime The value to assign firstTime.
*/
public void setFirstTime(String firstTime) {
this.firstTime = firstTime;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public int hashCode() {
return new HashCodeBuilder(7, 11)
.append(userId)
.append(role)
.append(userNumber)
.toHashCode();
}
/**
* Description of the Method
*
* @param o Description of the Parameter
* @return Description of the Return Value
*/
public boolean equals(Object o) {
if (!(o instanceof PlpUser)) {
return false;
}
PlpUser usr = (PlpUser) o;
return new EqualsBuilder()
//.appendSuper(super.equals(o))
.append(userId, usr.getUserId())
.append(role, usr.getRole())
.append(userNumber, usr.getUserNumber())
.isEquals();
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public String toString() {
StringBuffer sb = new StringBuffer("PlpUser[");
sb.append("userId=").append(userId);
sb.append(",role=").append(role);
sb.append(",userNumber=").append(userNumber);
sb.append(",firstName=").append(firstName);
sb.append(",lastName=").append(lastName);
sb.append(",password=").append(password);
sb.append(",firstTime=").append(firstTime);
sb.append("]");
return sb.toString();
}
}
Association Table
Code:
package us.wi.k12.madison.plp.model;
import java.io.*;
import java.util.*;
import java.util.List;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import org.apache.commons.lang.builder.*;
import org.apache.log4j.*;
/**
* Description of the Class
*
* @author Zeb Wollner
* @since March 4, 2005
* @hibernate.class schema="PLPTEST" table="STUDENT_LEARNING_STYLE_GOAL"
*/
public class StudentLearningStyleGoal implements Serializable {
private Logger logger = Logger.getLogger(getClass());
private Integer learningStyleGoalId;
private Integer goalId;
private Integer userId;
private PlpUser user;
private Goal goal;
/**
* Returns the value of learningStyleGoalId.
*
* @return The learningStyleLinkId value
* @hibernate.id column="LEARNING_STYLE_GOAL_ID" generator-class="hilo"
* @hibernate.generator-param name = "table" value = "PLPTEST.HILO"
* @hibernate.generator-param name = "column" value = "NEXT_HI"
*/
public Integer getLearningStyleGoalId() {
return learningStyleGoalId;
}
/**
* Sets the learningStyleGoalId attribute of the StudentLearningStyleGoal
* object
*
* @param learningStyleGoalId The new learningStyleGoalId value
*/
public void setLearningStyleGoalId(Integer learningStyleGoalId) {
this.learningStyleGoalId = learningStyleGoalId;
}
/**
* Returns the value of goalId.
*
* @return The lgoalId value
* @hibernate.property column="GOAL_ID" insert="false" update="false"
*/
public Integer getGoalId() {
return goalId;
}
/**
* Sets the value of goalId.
*
* @param goaleId The new goalId value
*/
public void setGoalId(Integer goaleId) {
this.goalId = goalId;
}
/**
* Returns the value of userId.
*
* @return The userId value
* @hibernate.property column="USER_ID" insert="false" update="false"
*/
public Integer getUserId() {
return userId;
}
/**
* Sets the value of userId.
*
* @param userId The value to assign userId.
*/
public void setUserId(Integer userId) {
this.userId = userId;
}
/**
* Returns the value of user.
*
* @return The user value
* @hibernate.many-to-one class="us.wi.k12.madison.plp.model.PlpUser"
* column="USER_ID" not-null="false" cascade="none"
*/
public PlpUser getUser() {
return user;
}
/**
* Sets the value of user.
*
* @param user The value to assign user.
*/
public void setUser(PlpUser user) {
this.user = user;
}
/**
* Returns the value of goal.
*
* @return The goal value
* @hibernate.many-to-one class="us.wi.k12.madison.plp.model.Goal"
* column="GOAL_ID" not-null="false" cascade="none"
*/
public Goal getGoal() {
return goal;
}
/**
* Sets the goal attribute of the StudentLearningStyleGoal object
*
* @param goal The new goal value
*/
public void setGoal(Goal goal) {
this.goal = goal;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public int hashCode() {
return new HashCodeBuilder(17, 19)
.append(learningStyleGoalId)
.append(goalId)
.append(userId)
.toHashCode();
}
/**
* Description of the Method
*
* @param o Description of the Parameter
* @return Description of the Return Value
*/
public boolean equals(Object o) {
if (!(o instanceof StudentLearningStyleGoal)) {
return false;
}
StudentLearningStyleGoal slsg = (StudentLearningStyleGoal) o;
return new EqualsBuilder()
//.appendSuper(super.equals(o))
.append(learningStyleGoalId, slsg.getLearningStyleGoalId())
.append(goalId, slsg.getGoalId())
.append(userId, slsg.getUserId())
.isEquals();
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public String toString() {
StringBuffer sb = new StringBuffer("StudentLearningStyleGoal:");
sb.append("learningStyleGoalId=").append(learningStyleGoalId);
sb.append(",goalId=").append(goalId);
sb.append(",userId=").append(userId);
sb.append(",user=").append(user);
sb.append(",goal=").append(goal);
return sb.toString();
}
}
Goal Table
Code:
package us.wi.k12.madison.plp.model;
import java.io.*;
import java.util.*;
import java.util.List;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import org.apache.commons.lang.builder.*;
import org.apache.log4j.*;
/**
* Description of the Class
*
* @author Zeb Wollner
* @since March 4, 2005
* @hibernate.class schema="PLPTEST" table="GOAL"
*/
public class Goal implements Serializable {
private Logger logger = Logger.getLogger(getClass());
private Integer goalId;
private String goalValue;
private Integer typeId;
private Set studentLearningStyleGoal;
/**
* Returns the value of studentLearningStyleGoal.
*
* @return The studentLearningStyleGoal value
* @hibernate.set inverse="true" cascade="save-update" lazy="false"
* @hibernate.collection-key column="GOAL_ID"
* @hibernate.collection-one-to-many
* class="us.wi.k12.madison.plp.model.StudentLearningStyleGoal"
*/
public Set getStudentLearningStyleGoal() {
return studentLearningStyleGoal;
}
/**
* Adds a feature to the StudentLearningStyleGoal attribute of the Goal
* object
*
* @param slsg The feature to be added to the StudentLearningStyleGoal
* attribute
*/
public void addStudentLearningStyleGoal(StudentLearningStyleGoal slsg) {
slsg.setGoal(this);
studentLearningStyleGoal.add(slsg);
}
/**
* Sets the value of studentLearningStyleGoal.
*
* @param studentLearningStyleGoal The value to assign
* studentLearningStyleGoal.
*/
public void setStudentLearningStyleGoal(Set studentLearningStyleGoal) {
this.studentLearningStyleGoal = studentLearningStyleGoal;
}
/**
* Returns the value of goalId.
*
* @return The goalId value
* @hibernate.id column="GOAL_ID" generator-class="hilo"
* @hibernate.generator-param name = "table" value = "PLPTEST.HILO"
* @hibernate.generator-param name = "column" value = "NEXT_HI"
*/
public Integer getGoalId() {
return goalId;
}
/**
* Sets the value of goalId.
*
* @param goalId The value to assign goalId.
*/
public void setGoalId(Integer goalId) {
this.goalId = goalId;
}
/**
* Returns the value of goalValue.
*
* @return The goalValue value
* @hibernate.property column="GOAL_VALUE"
*/
public String getGoalValue() {
return goalValue;
}
/**
* Sets the value of goalValue.
*
* @param goalValue The value to assign goalValue.
*/
public void setGoalValue(String goalValue) {
this.goalValue = goalValue;
}
/**
* Returns the value of typeId.
*
* @return The typeId value
* @hibernate.property column="TYPE_ID"
*/
public Integer getTypeId() {
return typeId;
}
/**
* Sets the value of typeId.
*
* @param typeId The value to assign typeId.
*/
public void setTypeId(Integer typeId) {
this.typeId = typeId;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public int hashCode() {
return new HashCodeBuilder(19, 23)
.append(goalId)
.append(goalValue)
.append(typeId)
.toHashCode();
}
/**
* Description of the Method
*
* @param o Description of the Parameter
* @return Description of the Return Value
*/
public boolean equals(Object o) {
if (!(o instanceof Goal)) {
return false;
}
Goal g = (Goal) o;
return new EqualsBuilder()
//.appendSuper(super.equals(o))
.append(goalId, g.getGoalId())
.append(goalValue, g.getGoalValue())
.append(typeId, g.getTypeId())
.isEquals();
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
public String toString() {
StringBuffer sb = new StringBuffer("Goal:");
sb.append("goalId=").append(goalId);
sb.append(",goalValue=").append(goalValue);
sb.append(",typeId=").append(typeId);
sb.append(",studentLearningStyleGoal=").append(studentLearningStyleGoal);
return sb.toString();
}
}
Mappings:
User Table
Quote:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping
>
<class
name="us.wi.k12.madison.plp.model.PlpUser"
table="PLPUSER"
schema="PLPTEST"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version"
>
<id
name="userId"
column="USER_ID"
type="java.lang.Integer"
>
<generator class="hilo">
<param name="table">PLPTEST.HILO</param>
<param name="column">NEXT_HI</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-PlpUser.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<set
name="studentLearningStyleGoal"
lazy="false"
inverse="true"
cascade="save-update"
sort="unsorted"
>
<key
column="USER_ID"
>
</key>
<one-to-many
class="us.wi.k12.madison.plp.model.StudentLearningStyleGoal"
/>
</set>
<property
name="role"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="ROLE"
/>
<property
name="userNumber"
type="java.lang.Integer"
update="true"
insert="true"
access="property"
column="USER_NUMBER"
/>
<property
name="firstName"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="FIRST_NAME"
/>
<property
name="lastName"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="LAST_NAME"
/>
<property
name="password"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="PASSWORD"
/>
<property
name="firstTime"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="FIRST_LOG_IN"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-PlpUser.xml
containing the additional properties and place it in your merge dir.
-->
</class>
<query name="us.wi.k12.madison.plp.model.readAllUsers"><![CDATA[
from PlpUser as PlpUser
]]></query>
<query name="us.wi.k12.madison.plp.model.readUserByUserNumber"><![CDATA[
from PlpUser as PlpUser where PlpUser.userNumber = :userNumber
]]></query>
</hibernate-mapping>
Association Table
Quote:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping
>
<class
name="us.wi.k12.madison.plp.model.StudentLearningStyleGoal"
table="STUDENT_LEARNING_STYLE_GOAL"
schema="PLPTEST"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version"
>
<id
name="learningStyleGoalId"
column="LEARNING_STYLE_GOAL_ID"
type="java.lang.Integer"
>
<generator class="hilo">
<param name="table">PLPTEST.HILO</param>
<param name="column">NEXT_HI</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-StudentLearningStyleGoal.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="goalId"
type="java.lang.Integer"
update="false"
insert="false"
access="property"
column="GOAL_ID"
/>
<property
name="userId"
type="java.lang.Integer"
update="false"
insert="false"
access="property"
column="USER_ID"
/>
<many-to-one
name="user"
class="us.wi.k12.madison.plp.model.PlpUser"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="USER_ID"
not-null="false"
/>
<many-to-one
name="goal"
class="us.wi.k12.madison.plp.model.Goal"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="GOAL_ID"
not-null="false"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-StudentLearningStyleGoal.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
Goal Table
Quote:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping
>
<class
name="us.wi.k12.madison.plp.model.Goal"
table="GOAL"
schema="PLPTEST"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version"
>
<id
name="goalId"
column="GOAL_ID"
type="java.lang.Integer"
>
<generator class="hilo">
<param name="table">PLPTEST.HILO</param>
<param name="column">NEXT_HI</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Goal.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<set
name="studentLearningStyleGoal"
lazy="true"
inverse="true"
cascade="save-update"
sort="unsorted"
>
<key
column="GOAL_ID"
>
</key>
<one-to-many
class="us.wi.k12.madison.plp.model.StudentLearningStyleGoal"
/>
</set>
<property
name="goalValue"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="GOAL_VALUE"
/>
<property
name="typeId"
type="java.lang.Integer"
update="true"
insert="true"
access="property"
column="TYPE_ID"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Goal.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
I put code simmliar to this into production the other day, and they wern't too hapy, it's creating way too many queries. So everywhere I had lazy set to false I set it to true, and that greatly improved the speed, but then I would get the following error anytime I tried to access the database after the initial time:
"SEVERE: Failed to lazily initialize a collection - no session or session was closed"
I just don't know what to do.
any help would be greatly appreicaited.
- Zeb