i have try to use Hibernate with this class that include
ArrayList :
but i get this exception:
expected type: java.util.ArrayList, actual value: org.hibernate.collection.PersistentList
(i must use Arraylist because just List is't Serializable and it's make me trouble)
this exception throw when the jpa entitymanager start.
this is the class:
package Entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import msg.AnsMsg;
public class Person implements Serializable {
static final long serialVersionUID = 1L;
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
private String _email;
private ArrayList <AnsMsg> msgList=new ArrayList<AnsMsg>();
public ArrayList <AnsMsg> getMsgList() {
return msgList;
}
public void setMsgList(ArrayList <AnsMsg> msgList) {
this.msgList = msgList;
}
public Person(){}
public String getEmail() {
return _email;
}
public void set_email(String _email) {
this._email = _email;
}
}
this is the hbm file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Apr 17, 2012 9:20:13 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="Entities.Person" table="PERSON">
<id name="id" type="long">
<column name="ID" />
<generator class="increment" />
</id>
<property name="_email" type="java.lang.String" access="field">
<column name="_EMAIL" />
</property>
<list name="msgList" inverse="false" table="ANSMSG" lazy="true">
<key>
<column name="ID" />
</key>
<list-index></list-index>
<one-to-many class="msg.AnsMsg" />
</list>
</class>
</hibernate-mapping>
how can i use java Arraylist with hibernate,
thanks in advance.
I think you need to associate the interface List and not the actual ArrayList class. If you see the PersistetList documentation http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/collection/PersistentList.html it implements java.util.List.
According to Hibernate Javadoc , PersistentList is also Serializable. Your POJO can have a reference to List, but in Runtime and instance of PersistentList -which is Serializable- should be used.
In a nutshell, just use List interface.
Related
I have a class ActivityLink which extends from Activity. ActivityLink has a property as private Activity link; i don't want touch table Activity but i want create second table as ActivityLink . I use Java 1.7 and latest version of hibernate.
How can i realize it in hibernate by xml mapping?
public class ActivityLink extends Activity implements Serializable {
private static final long serialVersionUID = 1L;
private Activity link;
public ActivityLink( Activity link ){ this.link = link; }
// getter en setter
}
public class Activity implements Serializable {
private static final long serialVersionUID = 1L;
private String identity;
public Character precision;
public Date requestedTime;
public Date effectiveTime;
public String performerId;
public Date schedulerTime;
public Double fractionQty;
public Short UserId;
public Double totalVolume;
public Double restVolume;
public Activity() { }
// getter en setter
}
Activity.hbm.xml file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field">
<class name="de.j2ee.order.ActivityLink"
table="order_db..ActivityLink">
<composite-id class="de.j2ee.order.PK" name="pk">
<key-property name="identity" column="Identity_" access="field"/>
</composite-id>
<version name="version" column="Version_" access="field" type="java.lang.Long"/>
<property name="identity" column="Identity_" update="false" insert="false"/>
<property name="precision" column="Precision_"/>
<property name="requestedTime" column="RequestedTime_"/>
<property name="effectiveTime" column="EffectiveTime_"/>
<property name="performerId" column="PerformerId_"/>
<property name="schedulerTime" column="SchedulerTime_"/>
<property name="fractionQty" column="FractionQty_"/>
<property name="userId" column="UserId_"/>
<property name="totalVolume" column="TotalVolume_"/>
<property name="restVolume" column="RestVolume_"/>
<union-subclass name="de.j2ee.order.ActivityLink" table="order_db..Activity">
<property name="link" />
</union-subclass>-->
</class>
</hibernate-mapping>
If you want to use a single table for Activity and ActivityLink then you have to use Table Per Class hierarchy strategy. Follow below link for details:
10.1.1. Table per class hierarchy
So your mapping should look something like this:
<class name="Activity" table="Activity">
<id name="identity" column="Identity">
</id>
<discriminator column="ACTIVITY_TYPE" type="string"/>
<subclass name="ActivityLink" discriminator-value="Activity_Link">
...
</subclass>
</class>
Update:
If you want to create a table for the sub-class ActivityLink then you need to use the below strategy:
10.1.2. Table per subclass
For example:
<class name="Activity" table="Activity">
<id name="identity" column="Identity">
</id>
<joined-subclass name="ActivityLink" table="Activity_Link">
<key column="Activity_ID"/>
...
</joined-subclass>
</class>
I need to save several child objects when creating the parent object. Ideally, I want to save them in one transaction, however, I keep getting an org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session.
In this example, a SubDiscipline has many SubdisciplinePlayers.
I feel that there's something wrong with the mapping
POJOs:
Subdiscipline.java
public class Subdiscipline {
private int id;
private int disciplineId;
private String name;
private List<SubdisciplinePlayer> subdisciplinePlayers;
public Subdiscipline() {
}
//standard constructors, getter & setters...
}
SubdisciplinePlayers.java
public class SubdisciplinePlayer implements Serializable {
private int idPlayers;
private int disciplineId;
private int subDisciplineId;
private int players;
private int minPlayers;
private int maxPlayers;
private Subdiscipline subdiscipline;
public SubdisciplinePlayer() {
}
//standard constructors, getter & setters...
}
Main.java:
public class Main {
#SuppressWarnings("unchecked")
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Subdiscipline sd = new Subdiscipline("soccer_" + (new Date()).getTime(), new Date(), new Date(), new Status(1) );
sd.setDisciplineId(4);
session.save(sd);
SubdisciplinePlayer sdp = new SubdisciplinePlayer();
sdp.setDisciplineId(sd.getDisciplineId());
sdp.setSubDisciplineId(sd.getId());
sdp.setSubdiscipline(sd);
sdp.setIdPlayers(555);
SubdisciplinePlayer sdp2 = new SubdisciplinePlayer();
sdp2.setDisciplineId(sd.getDisciplineId());
sdp2.setSubDisciplineId(sd.getId());
sdp2.setSubdiscipline(sd);
sdp2.setIdPlayers(457);
sd.setSubdisciplinePlayers(new ArrayList<SubdisciplinePlayer>());
sd.getSubdisciplinePlayers().add(sdp);
sd.getSubdisciplinePlayers().add(sdp2);
session.save(sd);
session.getTransaction().commit();
session.close();
}
}
Mappings
Subdiscipline Mapping
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.viralpatel.hibernate.Subdiscipline" table="sub_discipline">
<id name="id" column="sub_dis_id" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="disciplineId" column="dis_id" type="int"/>
<property name="name" column="sub_discipline" type="string"/>
<bag name="subdisciplinePlayers" table="sdis_players" inverse="true" cascade="all">
<key column="sub_dis_id" />
<one-to-many class="net.viralpatel.hibernate.SubdisciplinePlayer" />
</bag>
</class>
</hibernate-mapping>
SubdisciplinePlayer Mapping
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.viralpatel.hibernate.SubdisciplinePlayer" table="sdis_players">
<composite-id>
<key-property name="disciplineId" column="dis_id" type="int"/>
<key-property name="subDisciplineId" column="sub_dis_id" type="int" />
</composite-id>
<property name="idPlayers" column="id_players" type="int"/>
<property name="players" column="players" type="int"/>
<property name="minPlayers" column="min_players" type="int"/>
<property name="maxPlayers" column="max_players" type="int"/>
<many-to-one name="subdiscipline" class="net.viralpatel.hibernate.Subdiscipline" cascade="none" insert="false" update="false">
<column name="sub_dis_id"/>
</many-to-one>
</class>
</hibernate-mapping>
Exception thrown
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [net.viralpatel.hibernate.SubdisciplinePlayer#net.viralpatel.hibernate.SubdisciplinePlayer#1cd7e9c3]
You have declared composite key with fields disciplineId & subDisciplineId for your entity SubdisciplinePlayer.
Now in your program you are creating 2 instances of SubdisciplinePlayer with same composite id.
SubdisciplinePlayer sdp = new SubdisciplinePlayer();
sdp.setDisciplineId(sd.getDisciplineId());
sdp.setSubDisciplineId(sd.getId());
SubdisciplinePlayer sdp2 = new SubdisciplinePlayer();
sdp2.setDisciplineId(sd.getDisciplineId());
sdp2.setSubDisciplineId(sd.getId());
So when you call Session.save(sd), hibernate observed that you are trying to save 2 instances of SubdisciplinePlayer and throwing the exception as :
org.hibernate.NonUniqueObjectException: a different objectwith the same identifier
value was already associated with the session:
[net.viralpatel.hibernate.SubdisciplinePlayer#
net.viralpatel.hibernate.SubdisciplinePlayer#1cd7e9c3]
To fix the issue just make sure that the composite id of SubdisciplinePlayer should have different values as primary key should be unique.
Please use merge instead of save when you are trying with second time save.
sd.setSubdisciplinePlayers(new ArrayList<SubdisciplinePlayer>());
sd.getSubdisciplinePlayers().add(sdp);
sd.getSubdisciplinePlayers().add(sdp2);
session.merge(sd);
I listed out more ref for you.
Ref 1
Ref 2
How can I create (if I can) a template file for my hbm.xml files to use while they are being created from JAVA class?
I am using Jboss Hibernate Tools 3.5.1 and Eclipse Indigo
You can find a detailed description below.
Thanks for your help.
My JAVA classes are coded carefully to represent the sql table. they all have the same syntax.
for instance lets say I have the following table in my db:
Tests (id int primary key, TestData varchar(255), Type int)
a class referring to this table is:
public class TestData {
int id;
String testData;
int type;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTestData() {
return testData;
}
public void setTestData(String testData) {
this.testData = testData;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
When I create an automated hbm.xml file for this class it comes out as:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 12.Ara.2013 12:33:42 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.entegrator.framework.persistent.TestData" table="TESTDATA">
<id name="id" type="int">
<column name="ÝD" />
<generator class="assigned" />
</id>
<property name="testData" type="java.lang.String">
<column name="TESTDATA" />
</property>
<property name="type" type="int">
<column name="TYPE" />
</property>
</class>
</hibernate-mapping>
as you can see, my first problem is encoding.
what else I want to do is
property column names and class table name should be converted appropriately
id generator class should be "identity"
You have to change them manually if you are creating hbm file using eclipse.
Other options are you can use annotations or create files our own to remove this extra headache.!!!
you can get more about the same at Hibernate
I want to retrieve data from the database (Oracle) using Hibernate.
I want to select all columns from a view. The view has no primary key, so I used composite key in the Hibernate-mapping.
Firstly my class:
public class MyBean implements Serializable {
private MyBeanId compId;
private String col1;
private String col2;
// getters and setters
}
Where the MyBeanId class:
public class MyBeanId implements Serializable {
private int id1;
private int id2;
// getters and setters, hashCode and equals
}
The Hibernate mapping:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.mypackage">
<class name="MyBean" table="MY_TABLE">
<composite-id name="compId" class="MyBeanId ">
<key-property column="COL_ID1" name="id1" type="int"/>
<key-property column="COL_ID2" name="id2" type="int"/>
</composite-id>
<property name="col1" type="string">
<column name="COL1" />
</property>
<property name="col2" type="string">
<column name="COL2" />
</property>
</class>
</hibernate-mapping>
My DAO (MyBeanManagerImpl):
public List<MyBean> getMyBeans(Session session) {
try {
Criteria criteria = session.createCriteria(MyBean.class);
List<MyBean> list = criteria.list();
System.out.println(list.toString());
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
And my table MY_TABLE:
ID1,ID2,COL1,COL2
1,2,"a","b"
3,2,"c","d"
The result is an empty list. I've verified there's data in my table. When I use other managers in my service, there's no problem getting the result so there's no problem with the session.
There's no Exception thrown at all, so it is strange it doesn't get any result.
Add mapping-resource entry for the new mapping in yours hibernate-configuration -> session factory configuration like you have for other already mapped classes.
See the link https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Core_Reference_Guide/tutorial.html#tutorial-firstapp-configuration Chapter 'Hibernate configuration' there you have example of hibernate.cfg.xml. You need to add <mapping-resouce ... entry
i have three entity and Main(User) enitiy is in relation with other two entity,how can i retrive list of three entities from database in one query using hibernate
package hib.test;
import java.util.HashSet;
import java.util.Set;
public class Country {
private Integer id;
private String country;
private Set<User> userList = new HashSet<User>();
public Country() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
}
User.java
package hib.test;
public class User {
private Integer id;
private UserType userType;
private Country country;
public User() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public UserType getUserType() {
return userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
UserType.java
package hib.test;
import java.util.HashSet;
import java.util.Set;
public class UserType {
private Integer id;
private String userType;
private Set<User> userList = new HashSet<User>();
public UserType() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
}
country.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.Country" table="COUNTRY">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="country" type="java.lang.String">
<column name="COUNTRY" />
</property>
<set name="userList" table="USER" inverse="false" lazy="true">
<key>
<column name="ID" />
</key>
<one-to-many class="hib.test.User" />
</set>
</class>
</hibernate-mapping>
user.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.User" table="USER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<many-to-one name="userType" class="hib.test.UserType" fetch="join">
<column name="USERTYPE" />
</many-to-one>
<many-to-one name="country" class="hib.test.Country" fetch="join">
<column name="COUNTRY" />
</many-to-one>
</class>
</hibernate-mapping>
usertype.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.UserType" table="USERTYPE">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="userType" type="java.lang.String">
<column name="USERTYPE" />
</property>
<set name="userList" table="USER" inverse="false" lazy="true">
<key>
<column name="ID" />
</key>
<one-to-many class="hib.test.User" />
</set>
</class>
</hibernate-mapping>
How can i retrive List<User>, List<Country> and List<UserType> with one query
EDIT
public static List<UserType> getUserTypeList() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<UserType> list = null;
try {
transaction = session.beginTransaction();
list = session.createQuery("from UserType as u").list();
if (list != null) {
for (UserType uType : list)
Hibernate.initialize(uType.getUserList());
}
transaction.commit();
} catch (Exception e) {
if (transaction != null)
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
return list;
}
Actually I have 1 JTable and Two combo box each for UserType and Country
So when i select any data in combo box JTable data should be filter according to selected value and in memory it shoud be save selected UserType and Country object.
if you want relational data at once and memory is not an issue, do lazy="false"
try defining fetch type to EAGER on you user mapping, that way when you load your user it will load the country and userType.
You need three queries to do that:
select u from User u;
select ut from UserType ut;
select c from Country c;
EDIT:
If what you actually want is a list of all the user types, with the users of each user type, and the country of each user of each user type, all this loaded in a single query, then you need fetch joins, as explained in the Hibernate documentation:
select userType from UserType userType
left join fetch userType.users user
left join fetch user.country