Hibernate version:
2.1.6
Data model:
Code:
very shortened :
public class Contractor extends Persistent {
/**
* @hibernate.set lazy="true" inverse="true" cascade="all"
* @hibernate.collection-key column="contractor"
* @hibernate.collection-one-to-many class="com.xxx.model.Region"
*/
public Set getRegions() {
return regions;
}
}
public class Region extends Persistent implements Comparable {
/**
* @hibernate.set
* lazy="true"
* cascade="none"
* table="Region2Depot"
* @hibernate.collection-key
* column = "region"
* @hibernate.collection-many-to-many
* column="depot"
* class = "com.xxx.model.Depot"
*/
public Set getDepots() {
return depots;
}
}
public class Net extends Persistent {
/**
* @hibernate.set lazy="true" inverse="true" cascade="all"
* @hibernate.collection-key column="net"
* @hibernate.collection-one-to-many class="com.xxx.model.Depot"
*/
public Set getDepots() {
return depots;
}
}
public class Depot extends Persistent implements Comparable {
/**
* @hibernate.many-to-one not-null="true"
* @return
*/
public Net getNet() {
return net;
}
public void setNet( Net net ) {
this.net = net;
}
}
The meaning behind this is:
There is a net of shops (malls). A shop is called a Depot here. There is some producer that sells goods in these depots.
The producer is a Contractor entity here. The contractor divides depots into own defined regions. There may be many contractors
each having a different set of regions and depots assigned to them. That is why I used many to many relation ship.
Name and version of the database you are using:MySQL 4.1.3
Code between sessionFactory.openSession() and session.close():I have written a simple "import" tool that parses a text file and creates nets, depots, and regions.
Code:
private static void processLine( String str, Session session, Contractor cnt ) {
String[] temp = str.split( ";" );
String number = temp[ 0 ];
String netName = temp[ 1 ];
String city = temp[ 2 ];
String street = temp[ 3 ];
String buildingNumber = temp[ 4 ];
String appartmentNumber = temp[ 5 ];
String postalCode = temp[ 6 ];
String regionName = temp[ 7 ];
try {
Transaction tx = session.beginTransaction();
Net net = null;
Region region = null;
List regions = session.find( "from Region r where r.name = ?",
regionName,
Hibernate.STRING );
if ( !regions.isEmpty() ) {
region = (Region) regions.get( 0 );
} else {
region = new Region( regionName );
region.setContractor( cnt );
session.save( region );
}
List nets = session.find( "from Net n where n.name = ?",
netName,
Hibernate.STRING );
if ( !nets.isEmpty() ) {
net = (Net) nets.get( 0 );
} else {
net = new Net( netName );
session.save( net );
}
Depot depot = null;
Address address = new Address( city, postalCode, street, buildingNumber,
appartmentNumber );
session.save( address );
depot = new Depot( city );
depot.setAddress( address );
net.addDepot( depot );
session.save( depot );
session.saveOrUpdate( net );
region.addDepot( depot );
session.saveOrUpdate( region );
tx.commit();
// PROBLEM !!!
//session.evict( region );
} catch ( HibernateException e1 ) {
e1.printStackTrace();
}
}
There should be:
- an insert for net if there is no one of given name already
- an insert for region if there is no region of given name already
- an insert for each new depot
- an insert into region2depot to mark the "the depot is in that region" association.
My file has 249 lines. When I comment out session.evict( region ) from code I get only 105 inserts. Logs say that for some region.getDepots() collection there are no new rows to insert. With session.evict there are 249 as it should be.
The import is always done into the clean database. I also tried to do as many session.flush()es and save()s as I could. No change.
Statistics: 249 depots, 12 nets, 3 regions, 1 contractor. Not so much entities in session after all. Sounds like a bug.
WDYT?[/list]