-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Parent / child relation ship with <set> inverse attribute
PostPosted: Tue Nov 29, 2011 8:22 am 
Newbie

Joined: Wed Jul 23, 2008 1:59 am
Posts: 4
I am working on the part of learning Parent Child / relationship with hibernate , (Please refer my code below for reference)

When i am saving my parent object with <set> attribute inverse="false" (Stock.hbml.xml) , appropriate records are created in the parent and child as shown below in the queries ,

Hibernate: select max(stock_id) from stock_307
Hibernate: select max(daily_record_id) from stock_daily_record_307
Hibernate: insert into stock_307 (stock_code, stock_name, stock_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?


The only thing i dislike here is the last three update queries that get unnecessary fired here , for solving this issue I have done <set> attribute inverse="true" (Stock.hbml.xml)

This gives me the below error

Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("SCOTT"."STOCK_DAILY_RECORD_307"."STOCK_ID")


For solving the above problem ("ORA-01400: cannot insert NULL into") , I have make the not-null attribute as false in the file StockDailyRecord.hbm.xml
as <column name="stock_id" not-null="false" > ,after that queries are fired as intended as shown below , but stock_id which is a foreign key in the child table (stock_daily_record_307) does not contain any
value , this voilates the relationship

Hibernate: select max(stock_id) from stock_307
Hibernate: select max(daily_record_id) from stock_daily_record_307
Hibernate: insert into stock_307 (stock_code, stock_name, stock_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, daily_record_id) values (?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, daily_record_id) values (?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, daily_record_id) values (?, ?)


Please help me in achieving the goal that only minimum queries should be fired with <set> inverset = "true"(Stock.hbml.xml)
and not null should be true <column name="stock_id" not-null="true" > (StockDailyRecord.hbm.xml)



Refer the complete code below



public class StockTest {

public static void main(String args[]){

SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();
Session session = sessionfactory.openSession();
session.beginTransaction();

Stock stock = new Stock();
stock.setStock_code("12324");
stock.setStock_name("romoOne");

StockDailyRecord stkObj = new StockDailyRecord();
stkObj.setPrice_open(1212);

StockDailyRecord stkObj1 = new StockDailyRecord();
stkObj1.setPrice_open(2222);

StockDailyRecord stkObj2 = new StockDailyRecord();
stkObj2.setPrice_open(3333);

Set<StockDailyRecord> setObj = new HashSet<StockDailyRecord>();

setObj.add(stkObj);
setObj.add(stkObj1);
setObj.add(stkObj2);

stock.setStockDailyRecords(setObj);

session.save(stock);

session.flush();

session.beginTransaction().commit();

}
}



Stock.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">

<hibernate-mapping>
<class name="com.Stock" table="stock_307" >
<id name="stock_id">
<generator class="increment"></generator>
</id>
<set name="stockDailyRecords" table="stock_daily_record_307" inverse="true" cascade="all" >
<key column="stock_id" not-null="true"></key> <!--not-null="true" -->
<one-to-many class="com.StockDailyRecord" />
</set>
<property name="stock_code" column="stock_code"></property>
<property name="stock_name" column="stock_name"></property>
</class>


</hibernate-mapping>


StockDailyRecord.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">

<hibernate-mapping>

<class name="com.StockDailyRecord" table="stock_daily_record_307" >

<id name="daily_record_id">
<generator class="increment"></generator>
</id>

<property name="price_open" column="price_open"></property>

<many-to-one name="stock" class="com.Stock" insert="false" update="false" >
<column name="stock_id" not-null="false" ></column> <!--not-null="true" -->
</many-to-one>

</class>

</hibernate-mapping>







public class Stock implements java.io.Serializable {

private int stock_id;
String stock_code;
String stock_name;

Set<StockDailyRecord> stockDailyRecords ;//

public int getStock_id() {
return stock_id;
}
public void setStock_id(int stockId) {
stock_id = stockId;
}
public String getStock_code() {
return stock_code;
}
public void setStock_code(String stockCode) {
stock_code = stockCode;
}
public String getStock_name() {
return stock_name;
}
public void setStock_name(String stockName) {
stock_name = stockName;
}
public Set<StockDailyRecord> getStockDailyRecords() {
return stockDailyRecords;
}
public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) {
this.stockDailyRecords = stockDailyRecords;
}


}





public class StockDailyRecord implements java.io.Serializable{

private int daily_record_id;

int price_open;

private Stock stock;


public int getDaily_record_id() {
return daily_record_id;
}

public void setDaily_record_id(int dailyRecordId) {
daily_record_id = dailyRecordId;
}

public int getPrice_open() {
return price_open;
}

public void setPrice_open(int priceOpen) {
price_open = priceOpen;
}

public Stock getStock() {
return stock;
}

public void setStock(Stock stock) {
this.stock = stock;
}

}



hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@pc1226:1521:training123</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- mapping resource="hibernate/emp.hbm.xml"/-->
<!-- mapping resource="hibernate/address.hbm.xml"/-->
<mapping resource="hibernate/Stock.hbm.xml"/>
<mapping resource="hibernate/StockDailyRecord.hbm.xml"/>


</session-factory>

</hibernate-configuration>


Top
 Profile  
 
 Post subject: Re: Parent / child relation ship with <set> inverse attribute
PostPosted: Tue Nov 29, 2011 8:58 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Remove insert="false" update="false" from <many-to-one name="stock" class="com.Stock" insert="false" update="false" > in StockDailyRecord.hbm.xml


Top
 Profile  
 
 Post subject: Re: Parent / child relation ship with <set> inverse attribute
PostPosted: Tue Nov 29, 2011 10:05 am 
Newbie

Joined: Wed Jul 23, 2008 1:59 am
Posts: 4
after removing insert="false" update="false" from <many-to-one name="stock" class="com.Stock" insert="false" update="false" > in StockDailyRecord.hbm.xml

I am getting below error


Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: com.StockDailyRecord.stock
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:101)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:476)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:354)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)
at com.StockTest.main(StockTest.java:39)


Top
 Profile  
 
 Post subject: Re: Parent / child relation ship with <set> inverse attribute
PostPosted: Tue Nov 29, 2011 10:46 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
You'll never set the 'stock' for the StockDailyRecord:s. Read the parent/child example in the Hibernate documentation: http://docs.jboss.org/hibernate/core/3. ... child.html

This explains in detail how to work with bi-directional parent/child associations.


Top
 Profile  
 
 Post subject: Re: Parent / child relation ship with <set> inverse attribute
PostPosted: Wed Nov 30, 2011 8:38 am 
Newbie

Joined: Wed Jul 23, 2008 1:59 am
Posts: 4
thank you for providing the link for Hibernate documentation , i have gone through the link and got a flavour how parent /child
relationship works and got success to create child with parent .

But as far as Hibernate is concern its there for improving performance ,

Suppose i wants to create parent record with three child records for this case,
I have given ownership to the Stock ( i.e. <set> inverse = "false" in (Stock.hbml.xml)) , this will fire below queries


Hibernate: select max(stock_id) from stock_307
Hibernate: select max(daily_record_id) from stock_daily_record_307
Hibernate: insert into stock_307 (stock_code, stock_name, stock_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: insert into stock_daily_record_307 (price_open, stock_id, daily_record_id) values (?, ?, ?)
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?
Hibernate: update stock_daily_record_307 set stock_id=? where daily_record_id=?


My question is how can we tune this condition i.e remove the three unnecessary update calls , without making child as owner i.e
,parent should be the owner.


Top
 Profile  
 
 Post subject: Re: Parent / child relation ship with <set> inverse attribute
PostPosted: Wed Nov 30, 2011 8:45 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Don't think you can do that. The stock_id will only be part of the insert if the child is the owner.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.