create template for hibernate mapping files - java

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

Related

GWT + Hibernate many-to-one xml O/R Mapping: SerializationException

I'm currently working on a GWT + Hibernate project which should work together on an already defined and filled database. I receive an
com.google.gwt.user.client.rpc.SerializationException
when I query the database.
Here are my objects...
Database:
-- Table: asset
CREATE TABLE IF NOT EXISTS asset
(
isin VARCHAR(12) NOT NULL,
mic_code VARCHAR(4) NOT NULL DEFAULT 'n.a.',
name VARCHAR(255) NOT NULL,
type_id VARCHAR(36) NOT NULL,
PRIMARY KEY (isin, mic_code),
INDEX(isin, mic_code),
FOREIGN KEY (type_id) REFERENCES asset_type(id)
)ENGINE=InnoDB;
-- Table: asset_type
CREATE TABLE IF NOT EXISTS asset_type
(
id VARCHAR(36) NOT NULL,
type VARCHAR(40) NOT NULL,
PRIMARY KEY (id)
)ENGINE=InnoDB;
Asset.java:
public class Asset implements Serializable {
private String isin;
private String mic_code;
private String name;
private AssetType assetType;
public Asset() {
super();
}
...
AssetType.java
public class AssetType implements Serializable {
private String id;
private String type;
public AssetType() {
}
and finally the hibernate xml files:
Asset.hbm.xml
<hibernate-mapping>
<class name="com.mygwtproject.shared.model.Asset" table="ASSET">
<id name="isin" type="java.lang.String" access="field">
<column name="ISIN" />
<generator class="native" />
</id>
<property name="mic_code" type="java.lang.String" access="field">
<column name="MIC_CODE" />
</property>
<property name="name" type="java.lang.String" access="field">
<column name="NAME" />
</property>
<many-to-one name="assetType" class="com.mygwtproject.shared.model.types.AssetType" column="TYPE_ID" cascade="all" not-null="true"/>
</class>
</hibernate-mapping>
AssetType.hbm.xml
<hibernate-mapping>
<class name="com.mygwtproject.shared.model.types.AssetType" table="ASSET_TYPE">
<id name="id" type="java.lang.String" column="ID">
<generator class="native" />
</id>
<property name="type" type="java.lang.String" column ="TYPE" />
</class>
</hibernate-mapping>
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">*****</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/asset_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<mapping resource="com/mygwtproject/shared/model/Asset.hbm.xml" />
<mapping resource="com/mygwtproject/shared/model/types/AssetType.hbm.xml" />
</session-factory>
</hibernate-configuration>
from log:
Hibernate:
select
assettype0_.ID as ID1_1_0_,
assettype0_.TYPE as TYPE2_1_0_
from
ASSET_TYPE assettype0_
where
assettype0_.ID=?
09:43:09,139 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [ee5bb49a-dc95-403a-9f77-864a9c342f25]
09:43:09,142 TRACE BasicExtractor:78 - extracted value ([TYPE2_1_0_] : [VARCHAR]) - [Stock]
Starting Jetty on port 8888
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'com.mygwtproject.shared.model.types.AssetType_$$_jvst77c_0' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.mygwtproject.shared.model.types.AssetType#7d617ac9
so there is something wrong with my Asset -> AssetType mapping, but i cant find it. Any help is appreciated. thanks
edit:
mysql> select * from asset_type where id = 'ee5bb49a-dc95-403a-9f77-864a9c342f25';
returns
+--------------------------------------+-------+
| id | type |
+--------------------------------------+-------+
| ee5bb49a-dc95-403a-9f77-864a9c342f25 | Stock |
+--------------------------------------+-------+
1 row in set (0.00 sec)
Solution from here:
1. Create counterpart Data Transfer Objects and replace the hibernate objects.
AssetDTO.java
public class AssetDTO implements Serializable {
private String isin;
private String mic_code;
private String name;
private AssetTypeDTO assetType;
public AssetDTO() {
super();
}
public AssetDTO(String isin, String mic_code, String name,
AssetTypeDTO assetType) {
super();
this.isin = isin;
this.mic_code = mic_code;
this.name = name;
this.assetType = assetType;
}
//incl. Getter + Setter
}
AssetTypeDTO.java
public class AssetTypeDTO implements Serializable {
private String id;
private String type;
public AssetTypeDTO() {
super();
}
public AssetTypeDTO(String id, String type) {
super();
this.id = id;
this.type = type;
}
//incl. Getter + Setter
}
2. Add a new constructor to the hibernate objects.
Asset.java
...
public Asset(AssetDTO dto) {
this.isin = dto.getIsin();
this.mic_code = dto.getMic_code();
this.name = dto.getName();
AssetTypeDTO assetTypeDTO = dto.getAssetType();
if (assetTypeDTO != null) {
this.assetType = new AssetType(assetTypeDTO.getId(),
assetTypeDTO.getType());
}
}
...
AssetType.java
public AssetType(AssetTypeDTO dto) {
this.id = dto.getId();
this.type = dto.getType();
}
3. Modify your GWT RPC components.
Replace the Hibernate objects in
IService.java
public List<Asset> getAssets();
with the DTOs.
public List<AssetDTO> getAssets();
IServiceAsync.java
public void getAssets(AsyncCallback<List<Asset>> callback);
with
public void getAssets(AsyncCallback<List<AssetDTO>> callback);
4. Modify your service implementation.
ServiceImpl.java
...
#Override
public List<AssetDTO> getAssets() {
...
Query q = session.createQuery("from Asset");
List<Asset> assets = new ArrayList<Asset>(q.list());
List<AssetDTO> assetsDto = new ArrayList<AssetDTO>();
if (assets != null) {
for (Asset asset : assets) {
assetsDto.add(createAssetDTO(asset));
}
}
session.getTransaction().commit();
return assetsDto;
}
public AssetDTO createAssetDTO(Asset asset) {
AssetTypeDTO assetTypeDto = new AssetTypeDTO(asset.getAssetType()
.getId(), asset.getAssetType().getType());
AssetDTO result = new AssetDTO(asset.getIsin(), asset.getMicCode(),
asset.getName(), assetTypeDto);
return result;
}
...
5. Move the Hibernate objects (Asset, AssetType) to the server package, move the DTOs (AssetDTO, AssetTypeDTO) to the shared package and update the path in your Hibernate xml files.

how to extends class in hibernate which refer to a row in the same table by hbm mapping?

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>

org.hibernate.NonUniqueObjectException when saving a list of child objects

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

Hibernate criteria returns empty result

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

Hibernate with java ArrayList

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.

Categories