Please help me here. I am new to Hibernate. Done the setup successfully. But when I run the code with different values, the values in the table are getting over written. I've no idea what is going wrong. Here is my code:
UserDetails.java
package com.hibernate;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="User_Details")
public class UserDetails {
#Id
private int id;
private String name;
private String phonenumber;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
GetUserDetails.java
package com.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
#SuppressWarnings("deprecation")
public class GetUserDetails {
public static void main(String[] args) {
UserDetails ud = new UserDetails();
ud.setId(3);
ud.setName("User3");
ud.setPhonenumber("9988555774");
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(ud);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
When I run the above code, with the values "3", "User3", "9988555774" is getting inserted into the table.
But if I run the code again with the values "4", "User4", "9988547774", then the old value is getting over written and the new values are inserted correctly.
Please help me as I don't know what I'm missing.
I beleive you've added the following line in your hibernate.cfg.xml.
<property name="hbm2ddl.auto">create</property>
Try changing "create" to "update", as shown below:
<property name="hbm2ddl.auto">update</property>
Refer the following link for more info about the above property values:
Hibernate hbm2ddl.auto possible values and what they do?
Hibernate: hbm2ddl.auto=update in production?
Related
My main class is :
package com.ashwin.jpafirst;
import com.ashwin.jpafirst.model.Person;
import com.ashwin.jpafirst.reposit.PersonJpaRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class JpafirstApplication implements CommandLineRunner {
private Logger logger= LoggerFactory.getLogger(this.getClass());
#Autowired
PersonJpaRepository personJpaRepository;
public static void main(String[] args)
{
SpringApplication.run(JpafirstApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
logger.info("User id is ",personJpaRepository.findById(2));
}
}
Person.java
package com.ashwin.jpafirst.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="person")
public class Person {
#Id
#GeneratedValue
private int id;
#Column(name="name")
private String name;
private String location;
private Date dateOfBirth;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Person(int id, String name, String location, Date dateOfBirth) {
this.id = id;
this.name = name;
this.location = location;
this.dateOfBirth = dateOfBirth;
}
public Person() {
}
}
my application properties is:
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/jpaintro
spring.datasource.username = root
spring.datasource.password =
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
PersonJpaRepository.java
package com.ashwin.jpafirst.reposit;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.ashwin.jpafirst.model.Person;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional
public class PersonJpaRepository {
//connects to Databse
#PersistenceContext
EntityManager entityManager;
public Person findById(int id) {
return entityManager.find(Person.class, id);
}
}
I have also data saved in database as:
But when I try to receive the Person object by Id using
logger.info("User id is ",personJpaRepository.findById(2));
I am just getting as :
As Person object needs to print there,but the code is successfully compiling but I am not getting the information regarding the person.My code has no error but it is not retrieving the data.Why is the Person object not printing in the console?
I am trying to save data usign hsqldb and I am using hibernate 4.1.4.Final. My problem is I want to save data using persist but when I tried to do it's showing following error:
org.hibernate.PersistentObjectException: detached entity passed to persist: main.java.entity.Advocate
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:835)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:828)
at org.hibernate.engine.spi.CascadingAction$7.cascade(CascadingAction.java:315)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:844)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:819)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:823)
at main.java.service.LegalService.registerCase(LegalService.java:46)
at main.java.tester.Tester.registerCase(Tester.java:52)
at main.java.tester.Tester.main(Tester.java:28)
But when I use save method it worked.So I want to know how persist and save makes difference? and my entity classes are serialized.How to solve this persist error.
Here is my class
package main.java.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import main.java.businessTier.CaseTO;
import main.java.entity.Advocate;
import main.java.entity.Case;
public class LegalService {
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()). buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
public int registerCase(CaseTO caseTO) {
try
{
Session session;
session=sessionFactory.openSession();
session.beginTransaction();
Case c = new Case();
Advocate a = new Advocate();
a.setAdvocateId(caseTO.getAdvocateId());
c.setAdvocate(a);
c.setClientAge(caseTO.getClientAge());
c.setClientName(caseTO.getClientName());
c.setDate(caseTO.getDate());
c.setDescription(caseTO.getDescription());
session.persist(c);
session.getTransaction().commit();
return c.getCaseNo();
}
catch(Exception e){
e.printStackTrace();
return 0;
}
}
}
Here are my entity class
Advocate.java
package main.java.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
#Entity
#Table(name="Db_Advocate")
#DynamicInsert(value=true)
#DynamicUpdate(value=true)
public class Advocate {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="advocateId")
private Integer advocateId;
#Column(name="name")
private String name;
#Column(name="age")
private Integer age;
#Column(name="category")
private String category;
#Column(name="court")
private String court;
#Column(name="city")
private String city;
public Integer getAdvocateId() {
return advocateId;
}
public void setAdvocateId(Integer advocateId) {
this.advocateId = advocateId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getCourt() {
return court;
}
public void setCourt(String court) {
this.court = court;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Case.java
package main.java.entity;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
#Entity
#Table(name="DB_CASE")
#DynamicInsert(value=true)
#DynamicUpdate(value=true)
public class Case {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer caseNo;
#JoinColumn(name="advocateId")
#ManyToOne(cascade=CascadeType.ALL)
private Advocate advocate;
private String clientName;
private Integer clientAge;
private String description;
private Date date;
public Integer getCaseNo() {
return caseNo;
}
#Column(name="caseNo")
public void setCaseNo(Integer caseNo) {
this.caseNo = caseNo;
}
public Advocate getAdvocate() {
return advocate;
}
public void setAdvocate(Advocate advocateId) {
this.advocate = advocateId;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public Integer getClientAge() {
return clientAge;
}
public void setClientAge(Integer clientAge) {
this.clientAge = clientAge;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getDate() {
return date;
}
#Column(name="data",nullable=true)
public void setDate(Date date) {
this.date = date;
}
}
First you need to understand behaviour of persist().
Below are the links that will help you understand the behaviour
Whats the difference between persist() and save() in Hibernate?
http://javarevisited.blogspot.in/2012/09/difference-hibernate-save-vs-persist-and-saveOrUpdate.html
Now in order to solve this problem in your code .. use merge() instead of persist().
Why persist() gave the exception
persist() does not work for detached objects .You need to know how hibernate determines whether an object is detached or not.
UPDATE
Why the identifier generation strategy auto solved your problem
As i mentioned above that you need to understand the rules by which hibernate identifies whether an object is detached or transient. Below are the rule
If the the entity has a null value for identifier or the version attribute is null it is considered as transient other wise detached.
If you use auto-generated identifiers, and the identifier is not null, then Hibernate considers it as a detached entity.
If you are using assigned identifier strategy then hibernate will issue a fetch to determine whether the identifier exists in db based on that your entity will be either transient or detached.
Now that being said .. we analyse your code.
In your code you have Advocate entity whose identifier strategy is IDENTITY.In the below code
Case c = new Case();
Advocate a = new Advocate();
a.setAdvocateId(caseTO.getAdvocateId());
You are setting the identifier property of Advocate instance manually.At the time of flush when transaction commits ,hibernate will see that the identifier generation strategy is IDENTITY and the identifier value is set in the advocate instance hence it will conclude that the entity instance is detached (this is from the rule 1 described above).And hence the persist() method gave exception for the advocate instance as it is deemed to be detached from hibernate.
From rule 2 we can say that your code will not work just by changing the generation strategy to auto.You might have done some other changes.
I have tried your code on my system it is giving the same exception even if i change the generation strategy to auto which is in consistent with the rules
You might be doing something different in your code .. please check and update.
Please also post the identifier that you are setting in the advocate and the actual identifier generated for that advocate in database with auto generation strategy, that might be helpful
Please Add below code at id
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Then persist will work
Is there anyway I can have the effect of #ElementCollection without actually having this annotation? I am using Hibernate 3.3, while #ElementCollection and #CollectionTable is only supported for Hibernate 3.5 and beyond. But I really need to use these annotations, for a case like this:
http://www.concretepage.com/hibernate/elementcollection_hibernate_annotation
(Where we get the List of Strings rather than List of the full entity)
You can use the <element> tag to do the same operation, refer to this link from hibernate documentation:
7.2.3. Collections of basic types and embeddable objects
The example given in the link is :
<element
column="column_name" (1)
formula="any SQL expression" (2)
type="typename" (3)
length="L"
precision="P"
scale="S"
not-null="true|false"
unique="true|false"
node="element-name"
/>
1 column (optional): the name of the column holding the collection element values.
2 formula (optional): an SQL formula used to evaluate the element.
3 type (required): the type of the collection element.
Refer to this link for an example:
Collection Mapping
Star.java
private Set<String> planets = new HashSet<String>();
Star.hbm.xml
<set name="planets" table="star_planet">
<key column="star_id" />
<element type="text"/>
</set>
Update:
You have to use either xml mapping or annotations for a given entity class but not both at a time.
If you want to see examples only using annotations then there are so many available if you search in Google, please check and let me know if you have issues in implementing them.
Finally, yes it works with Set of Strings, integers or Long etc.
Update:
Here is a simple example that shows how to use element collections:
User.java
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
#Entity
#Table(name = "TB_User")
public class User {
#Id
#GeneratedValue
private int id;
private String name;
#ElementCollection
#CollectionTable(name = "Addresses", joinColumns = #JoinColumn(name = "user_id"))
#AttributeOverrides({ #AttributeOverride(name = "street1", column = #Column(name = "fld_street")) })
public Set<Address> addresses = new HashSet<Address>();
public User() {
}
public User(String name, Address... addresses){
this.name = name;
this.addresses.addAll(Arrays.asList(addresses));
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Address> getAddresses() {
return addresses;
}
public void setAddresses(Set<Address> addresses) {
this.addresses = addresses;
}
}
Address.java
import javax.persistence.Embeddable;
#Embeddable
public class Address {
private String street1;
public Address() {
}
public Address(String street1) {
this.street1 = street1;
}
public String getStreet1() {
return street1;
}
public void setStreet1(String street1) {
this.street1 = street1;
}
#Override
public String toString() {
return street1;
}
}
Simple logic to test this:
private static void showUsers() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
List<User> users = session.createQuery("from User").list();
for (User user : users) {
System.out.println(user.getName() + " -- > " + user.getAddresses());
}
session.getTransaction().commit();
}
private static void saveUsers() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
User user1 = new User("U1", new Address("A1"), new Address("A11"));
User user2 = new User("U2", new Address("A2"));
session.save(user1);
session.save(user2);
session.getTransaction().commit();
}
i am having three classes one is USER, second Vehicle and third is notfound_test.
In USER class i declared vehicle as Collection as follow.
Collection vehicle=new ArrayList();
And also having getters and setters of it.
So, my question is how i can retrieve data from database i am using hibernate?
I tried following code.
i am unable from getting data in JOPTIONPANE OF VEHICLE IN THIRD CLASS.i wanted the associated data
package org.notfound.annotation;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class User {
#Id #GeneratedValue
private int id;
private String name;
#OneToMany
Collection<Vehicle> vehicle=new ArrayList<Vehicle>();
public Collection<Vehicle> getVehicle() {
return vehicle;
}
public void setVehicle(Collection<Vehicle> vehicle) {
this.vehicle = vehicle;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package org.notfound.annotation;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
#Entity
public class Vehicle {
#Id #GeneratedValue
private int vehicle_id;
private String vehicle_name;
#ManyToOne
private User user=new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getVehicle_id() {
return vehicle_id;
}
public void setVehicle_id(int vehicle_id) {
this.vehicle_id = vehicle_id;
}
public String getVehicle_name() {
return vehicle_name;
}
public void setVehicle_name(String vehicle_name) {
this.vehicle_name = vehicle_name;
}
}
package org.notfound.annotation;
import javax.swing.JOptionPane;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Notfound_test {
public static void main(String[] args) {
User user=new User();
Vehicle vehicle=new Vehicle();
Vehicle vehicle2=new Vehicle();
user.setName("NIRAV J. KAMANI");
vehicle.setVehicle_name("CHEVROLET CRUIZE");
vehicle2.setVehicle_name("MARUTI ERTIGA");
vehicle.setUser(user);
vehicle2.setUser(user);
user.getVehicle().add(vehicle);
user.getVehicle().add(vehicle2);
SessionFactory sessionfactory=new Configuration().configure().buildSessionFactory();
Session session=sessionfactory.openSession();
/*session.beginTransaction();
session.save(user);
session.save(vehicle);
session.save(vehicle2);
session.getTransaction().commit();
session.close();*/
session.beginTransaction();
user=(User) session.get(User.class, 1);
vehicle=(Vehicle) session.get(Vehicle.class, 1);
vehicle2=(Vehicle) session.get(Vehicle.class, 2);
JOptionPane.showMessageDialog(null, user.getId()+" "+user.getName()+" "+user.getVehicle().toString(), "INFORMATION", JOptionPane.INFORMATION_MESSAGE);
session.close();
}
}
As always, you forgot the mappedBy annotation on the OneToMany. It's a bidirectional OneToMany association, and the one side must thus be the inverse side of the many side, as explained in the documentation:
#OneToMany(mappedBy = "user")
private Collection<Vehicle> vehicles = new ArrayList<Vehicle>();
I also renamed the fields to vehicles, since it's a collection, and thus contains several ones.
EDIT:
Your comment shows that the 2 vehicles are printed:
[org.notfound.annotation.Vehicle#37ed25, org.notfound.annotation.Vehicle#aec63]
^-- first vehicle ^-- second vehicle
^-- brackets, indicating that it's a collection ------------------------------^
If you want them to be printed is a different way than the dafult way, you need to override the toString() method in vehicle, as for any Java object.
I am using Hibernate as the ORM for a database that has a number of foreign key relationships. The problem is that sometimes I want to fetch these related datasets and sometimes I do not, so on these collections I have set "fetch" to "lazy". Unfortunately, every time I try to serialize these objects Hibernate will throw a LazyInitializationException, because the session is closed. Using an OpenSessionInView filter simply causes Hibernate to populate these collections anyway, thus defeating the whole purpose of having a lazy collection in the first place.
Is there a simple way to serialize or otherwise extract the data populated in the POJO without triggering the LIE, and without having to populate all of the lazy collections?
EDIT: Here is some example code I am trying to get working, dealing with two tables, "Departments" and "Employees," which is the child in a one-to-many relationship with Departments. I want to be able to view the Departments listed in the database, without having to load all of the Employees that belong to said Departments:
Departments:
package com.test.model;
// Generated Apr 7, 2012 7:10:28 PM by Hibernate Tools 3.4.0.CR1
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Departments generated by hbm2java
*/
#Entity
#Table(name="Departments"
,catalog="test"
)
public class Departments implements java.io.Serializable {
private Integer id;
private String name;
private Set<Employees> employeeses = new HashSet(0);
public Departments() {
}
public Departments(String name) {
this.name = name;
}
public Departments(String name, Set employeeses) {
this.name = name;
this.employeeses = employeeses;
}
#Id #GeneratedValue(strategy=IDENTITY)
#Column(name="Id", unique=true, nullable=false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name="Name", nullable=false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch=FetchType.LAZY, mappedBy="departments")
public Set<Employees> getEmployeeses() {
return this.employeeses;
}
public void setEmployeeses(Set employeeses) {
this.employeeses = employeeses;
}
}
Employees:
package com.test.model;
// Generated Apr 7, 2012 7:10:28 PM by Hibernate Tools 3.4.0.CR1
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* Employees generated by hbm2java
*/
#Entity
#Table(name="Employees"
,catalog="test"
)
public class Employees implements java.io.Serializable {
private Integer id;
private Departments departments;
private String firstName;
private String lastName;
public Employees() {
}
public Employees(Departments departments, String firstName, String lastName) {
this.departments = departments;
this.firstName = firstName;
this.lastName = lastName;
}
#Id #GeneratedValue(strategy=IDENTITY)
#Column(name="Id", unique=true, nullable=false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="DepartmentsId", nullable=false)
public Departments getDepartments() {
return this.departments;
}
public void setDepartments(Departments departments) {
this.departments = departments;
}
#Column(name="FirstName", nullable=false)
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name="LastName", nullable=false)
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
My action class (which gets serialized by the Struts2 XSLT result):
package com.test.view;
import java.util.List;
import java.util.Iterator;
import com.opensymphony.xwork2.ActionSupport;
import com.test.controller.DepartmentsManager;
import com.test.model.Departments;
import com.test.util.HibernateUtil;
public class DepartmentsAction extends ActionSupport {
private DepartmentsManager departmentsManager;
private List<Departments> departmentsList;
public DepartmentsAction() {
this.departmentsManager = new DepartmentsManager();
}
public String list() {
this.departmentsList = departmentsManager.list();
System.out.println("Execute called");
HibernateUtil.createDTO(departmentsList);
return SUCCESS;
}
public List<Departments> getDepartmentsList() {
return departmentsList;
}
public void setDepartmentsList(List<Departments> departmentsList) {
this.departmentsList = departmentsList;
}
}
My Manager class (which the Action class calls to populate the list of Departments):
package com.test.controller;
import java.util.List;
import java.util.Iterator;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import com.test.model.Departments;
import com.test.util.HibernateUtil;
public class DepartmentsManager {
public List<Departments> list() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<Departments> set = null;
try {
Query q = session.createQuery("FROM Departments");
/*Query q = session.createQuery("FROM Departments d JOIN FETCH d.employeeses e");*/
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
set = (List<Departments>) q.list();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}
session.getTransaction().commit();
return set;
}
}
Lazy collections work only within the scope of the transaction (where the owning entity was retrieved from a DB). In other words, you should not pass a Hibernate entity with non-loaded lazy sub-entities or collections outside the transaction scope.
You need either to build another entity or use lazy="false" if you want to pass an entity to JSP, or serialization code or anything else.
Two simple ways to manage lazy loading within view :
Using a Transaction view (consisting in wrapping view calls into JTA transaction (application-managed for instance)
Using an extented persistence context in your bean and flushing it explicitely when you've done with it, that means as soon as you were able to load your lazy objects.
For more information, check this post and the answer that belongs to it:
JPA lazy loading Collections in JSF view - better way than using Filters?