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>
|