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.  [ 5 posts ] 
Author Message
 Post subject: Hibernate does not rollback all changes
PostPosted: Thu Mar 27, 2008 12:24 pm 
Newbie

Joined: Thu Mar 27, 2008 11:45 am
Posts: 10
Location: Russia
Hi all.

I'm not sure but may be it is bug.

In my test application I try to make inheritance hierarchy usind "Table per subclass" method.

So in test app I have different locations: streets, buildings, rooms.

And I create next database structure for it:

Code:
DROP TABLE IF EXISTS locations_third;
create table locations_third (
   id int unsigned NOT NULL auto_increment,
   name varchar(50) NOT NULL,
   primary key (id)
);

DROP TABLE IF EXISTS streets_third;
create table streets_third (
   id int unsigned NOT NULL auto_increment,
   prestig int,
   primary key (id)
);

DROP TABLE IF EXISTS buildings_third;
create table buildings_third (
   id int unsigned NOT NULL auto_increment,
   street_id int NOT NULL,
   num_stores int,
   primary key (id)
);

DROP TABLE IF EXISTS rooms_third;
create table rooms_third (
   id int unsigned NOT NULL auto_increment,
   building_id int NOT NULL,
   level int,
   primary key (id)
);

insert into locations_third (id, name) values
   (1, 'dzerjinka'), (2, 'tverskaya'), (3, 'dolgoozernaya'),
   (4, 'dom N 19'), (5, 'DK Aluminka'), (6, 'dom N 33'),
   (7, 'Hotel One *****'), (8, 'Cazino Gold Pavlin'),
   (9, 'dom 2A'), (10, 'dom 4'),
   
   (11, 'parikmaherskaya'), (12, 'my flat'), (13, 'hol'), (14, 'kino'),   
   (15, 'magazin'), (16, 'hol'), (17, 'restoran'), (18, 'pocker'), (19, 'flat 119(my)'), (20, 'flat 1');

insert into streets_third (id, prestig) values
   (1, 103),
   (2, 110),
   (3, 106);

insert into buildings_third (id, num_stores, street_id) values
   (4, 105, 1),
   (5, 104, 1),
   (6, 109, 1),
   (7, 107, 2),
   (8, 103, 2),
   (9, 107, 3),
   (10, 103, 3);

insert into rooms_third (id, level, building_id) values
   (11, 101, 4),
   (12, 105, 4),
   (13, 101, 5),
   (14, 102, 5),
   (15, 101, 6),
   (16, 101, 7),
   (17, 102, 7),
   (18, 101, 8),
   (19, 107, 9),
   (20, 101, 10);


Hibernate mapping file is:
Code:
<?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="at.db.polimorph.third.Location" table="locations_third">
        <id name="id" column="id" type="integer">
            <generator class="native"/>
        </id>
        <property name="name" column="name" type="string"/>

        <joined-subclass name="at.db.polimorph.third.Street" table="streets_third">
            <key column="id"/>
            <property name="prestigiousness" column="prestig" type="integer"/>
            <set name="buildings" cascade="all">
                <key column="street_id"/>
                <one-to-many class="at.db.polimorph.third.Building" not-found="ignore"/>
            </set>
        </joined-subclass>

        <joined-subclass name="at.db.polimorph.third.Building" table="buildings_third">
            <key column="id"/>
            <property name="numberOfStoreys" column="num_stores" type="integer"/>
            <many-to-one name="street" class="at.db.polimorph.third.Street" column="street_id" not-found="ignore"/>
            <set name="rooms" cascade="all">
                <key column="building_id"/>
                <one-to-many class="at.db.polimorph.third.Room" not-found="ignore"/>
            </set>
        </joined-subclass>

        <joined-subclass name="at.db.polimorph.third.Room" table="rooms_third">
            <key column="id"/>
            <property name="level" column="level" type="integer"/>
            <many-to-one name="building" class="at.db.polimorph.third.Building" column="building_id" not-found="ignore"/>
        </joined-subclass>

    </class>
</hibernate-mapping>


And java code is:
Code:
package at.db.polimorph.third;
public abstract class Location {
    private Integer id;
    private String name;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


Code:
package at.db.polimorph.third;
import java.util.Set;
public class Street extends Location {
    private Set<Building> buildings;
    private Integer prestigiousness;
    public Set<Building> getBuildings() {
        return buildings;
    }
    public void setBuildings(Set<Building> buildings) {
        this.buildings = buildings;
    }
    public Integer getPrestigiousness() {
        return prestigiousness;
    }
    public void setPrestigiousness(Integer prestigiousness) {
        this.prestigiousness = prestigiousness;
    }
    public void addBuilding(Building building) {
        buildings.add(building);
        building.setStreet(this);
    }
    public String toString() {
        return "STREET: " + getName() + " prestigiousness[" + prestigiousness +"]";
    }
}


Code:
package at.db.polimorph.third;
import java.util.Set;
public class Building extends Location {
    private Street street;
    private Set<Room> rooms;
    private Integer numberOfStoreys;
    public Street getStreet() {
        return street;
    }
    public void setStreet(Street street) {
        this.street = street;
    }
    public Set<Room> getRooms() {
        return rooms;
    }
    public void setRooms(Set<Room> rooms) {
        this.rooms = rooms;
    }
    public Integer getNumberOfStoreys() {
        return numberOfStoreys;
    }
    public void setNumberOfStoreys(Integer numberOfStoreys) {
        this.numberOfStoreys = numberOfStoreys;
    }
    public void addRoom(Room room) {
        rooms.add(room);
        room.setBuilding(this);
    }
    public String toString() {
        return "BUILDING: " + getName() + " numberOfStoreys[" + numberOfStoreys +"]";
    }
}


Code:
package at.db.polimorph.third;
public class Room extends Location {
    private Building building;
    private Integer level;
    public Building getBuilding() {
        return building;
    }
    public void setBuilding(Building building) {
        this.building = building;
    }
    public Integer getLevel() {
        return level;
    }
    public void setLevel(Integer level) {
        this.level = level;
    }
    public String toString() {
        return "ROOM: " + getName() + " level[" + level +"]";
    }
}



So this code works fine:
I can get locations
List<Location> locslist = sn.createCriteria(Location.class).list();

I can get streets:
List<Street> streets = sn.createCriteria(Street.class).list();
And so on.

I can create new Building and add it to some Street:
Code:
Street street = (Street) sn.get(Location.class, 1);
Building building = new Building();
building.setName("house number 156");
building.setNumberOfStoreys(25);
street.addBuilding(building);
sn.save(street);


BUT when I try to do silly thing, I have problems.
I add new Building so:
Code:
Street street = (Street) sn.get(Location.class, 1);
Building building = new Building();
building.setName("house number 157");
building.setNumberOfStoreys(18);
street.getBuildings().add(building);
sn.save(street);


Note that I used:
street.getBuildings().add(building);

Instead of:
street.addBuilding(building);

So now building does not have street.

And when I try to commit transaction i get Exception:
Code:
Hibernate: insert into locations_third (name) values (?)
Hibernate: insert into buildings_third (num_stores, street_id, id) values (?, ?, ?)
2008.03.27-19:16:03,861 ERROR JDBCExceptionReporter : Column 'street_id' cannot be null
org.hibernate.exception.ConstraintViolationException: could not insert: [at.db.polimorph.third.Building]
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2640)
   at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
   at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
   at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
   at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:218)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
   at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
   at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
   at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
   at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at at.TestPolimorph_ThirdCase.main(TestPolimorph_ThirdCase.java:72)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'street_id' cannot be null
   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
   at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1541)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1455)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1440)
   at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2250)
   


Of course I catch it and make rollback:
sn.getTransaction().rollback();

And I expect that two inserts will be rolled back:
insert into locations_third (name) values (?)
insert into buildings_third (num_stores, street_id, id) values (?, ?, ?)

But actually first insert is not rolled back.

I use next configuration:
java 1.5
hibernate3.jar
mysql_5.0.45


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 7:57 am 
Regular
Regular

Joined: Fri May 12, 2006 4:05 am
Posts: 106
Perhaps your DB-connection is running in auto-commit-mode?
Just check your hibernate.cfg-file and make sure that autocommit is false.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 31, 2008 7:25 am 
Newbie

Joined: Thu Mar 27, 2008 11:45 am
Posts: 10
Location: Russia
Well, I thought that hibernate change autocommit mode to false automatically when I begin transaction?!

But in any case I tried to do what you say. I add in hibernate config file next property:

<property name="connection.autocommit">false</property>

And even after this strange situation still occurs:
First insert is not rolled back


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 31, 2008 8:29 am 
Beginner
Beginner

Joined: Fri Aug 24, 2007 4:46 am
Posts: 36
Location: Bielefeld / Germany
Hi,

I'm no MySQL-expert, but as far as I know MySQL doesn't work transactional per default (MyISAM-engine), you'll need to use InnoDB-engine for proper transactions:

http://dev.mysql.com/doc/refman/5.0/en/ ... tions.html

HTH, Maik


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 31, 2008 11:15 am 
Newbie

Joined: Thu Mar 27, 2008 11:45 am
Posts: 10
Location: Russia
2 mjablonski
Thanks a lot.
I changed engine to InnoDB and now it works!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.