-->
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.  [ 2 posts ] 
Author Message
 Post subject: RollbackException thrown when adding ManyToOne relationship
PostPosted: Mon Apr 28, 2014 4:40 pm 
Newbie

Joined: Mon Apr 28, 2014 4:34 pm
Posts: 2
Scenario: I have a JSF 2.1 webapp running on a tomcat server, with hibernate implementing the jpa interface and mysql database.
Users of the webapp are registered as an Entity on the database, and there are a group of data called Rooms, that have their own Entity, where users have access as proprietary or as external managers. To save the concept of "external management" on the database i have a proper Entity for every management; the external management are saved as a OneToMany relathionship on the User Entity.

Problem: For some odd reason, adding the code for a foreign key to the managed room in the External Management Entity with a ManyToOne relationship, breaks up Hibernate: any update to the list of external management property on the User, when that foreign key is present, throws RollbackException - "Transaction marked as rollback only":

Code:
Caused by: it.katuiros.core.db.dao.DataAccessException: Data Access error while doing final commit.
at it.katuiros.core.db.dao.impl.GenericDaoImpl.closeDataAccess(GenericDaoImpl.java:222)
at it.katuiros.core.db.dao.impl.GenericDaoImpl.update(GenericDaoImpl.java:96)
at it.katuiros.appLogic.PersistenceTest.saveTestData(PersistenceTest.java:157)
at it.katuiros.beans.generics.TestBean.<init>(TestBean.java:44)
... 67 more

Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:74)
at it.katuiros.core.db.dao.impl.GenericDaoImpl.closeDataAccess(GenericDaoImpl.java:217)
... 70 more

As you probably know, the sad thing about those RollbackException in Hibernate is that they are UNDEBUGGABLE!

CODE
the User entity:

Code:
@Entity
@Table(name = "USER")
@Access(AccessType.FIELD)
public class User extends DataModelEntity {
    /**
     * Serialization ID
     */
    private static final long serialVersionUID = -1154710247841840471L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Basic(optional = false)
    @Column(name = "ID")
    protected int id;

    @NotNull
    @Column(name = "USERNAME", unique = true)
    protected String username;

    @NotNull
    @Column(name = "PASSWORD")
    protected String password;

    @NotNull
    @Column(name = "EMAIL", unique = true)
    protected String email;

    @Column(name = "FIRST_NAME")
    protected String firstName;

    @Column(name = "LAST_NAME")
    protected String lastName;

    @Column(name = "PHONE")
    protected String telefono;

    @ManyToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Basic(optional = false)
    @JoinColumn(name = "FAVORITE_ROOMS", referencedColumnName = "ID", updatable = true)
    protected Set<Room> favoriteRooms;

    @OneToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Basic(optional = false)
    @JoinColumn(name = "REGISTERED_ROOMS", referencedColumnName = "ID", updatable = true)
    protected Set<Room> registeredRooms;

    @OneToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Basic(optional = true)
    @JoinColumn(name = "EXTERNAL_MANAGEMENTS", referencedColumnName = "ID", updatable = true)
    protected Set<ExternalRoomManagementPermissions> externalManagements;

    @OneToOne
    @JoinColumn(name = "AVATAR", referencedColumnName = "ID", updatable = true)
    protected Image avatar;

    ... constructors and getters/setters ...
}


The External Management Entity

Code:
@Entity
@Table(name = "EXTERNAL_ROOM_MANAGEMENT_PERMISSIONS")
@Access(AccessType.FIELD)
public class ExternalRoomManagementPermissions extends DataModelEntity {

    /**
     * Serialization ID
     */
    private static final long serialVersionUID = 7122195658297760351L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Basic(optional = false)
    @Column(name = "ID")
    private int id;

    /* CRIMINAL CODE */
    @ManyToOne
    @NotNull
    @JoinColumn(name = "MANAGED_ROOM", referencedColumnName = "ID")
    private Room managedRoom;
    /* END OF CRIMINAL CODE */

    ... constructors and getters/setters ...
}

I will not post the Room Entity code, as it is not so important.

and this is the piece of code where the user with a set of external managements is updated on the database and the exception is thrown:

Code:
this.externalManagement1 = new ExternalRoomManagementPermissions(this.room4);
this.dbAccessor.saveData(this.externalManagement1);
this.externallyManagedRoomsForUser1.add(this.externalManagement1);
this.user1.setRegisteredRooms(this.registeredRoomsForUser1);
this.user2.setRegisteredRooms(this.registeredRoomsForUser2);
userDao.update(this.user1);
userDao.update(this.user2);
this.user1.setExternalManagements(this.externallyManagedRoomsForUser1);

userDao.update(this.user1);  // <---- EXPLODING LINE

The last two lines are the critical step: if the External Management Entity has that "criminal code" about the ManyToOne relationship to the managed room, the userDao.update(...) will throw the exception; if the "criminal code" is omitted, the userDao.update(...) will NOT throw the exception.

(The room has already been previously persisted to the database before i use it in that last code segment)

Question: sadly i need that ManyToOne relationship to the managed room, do you know why it breaks the persistence up?

Post-Scriptum: i tried to change the ManyToOne relationship to a OneToOne but it had no effect.


Top
 Profile  
 
 Post subject: Re: RollbackException thrown when adding ManyToOne relationship
PostPosted: Tue Apr 29, 2014 9:35 am 
Newbie

Joined: Mon Apr 28, 2014 4:34 pm
Posts: 2
OK!

I think i've found the problem through intensive debug and extensive use of breakpoints... i've never went so much down in debugging in my whole life as a programmer! The causing error was incredibly stupid:

Code:
"org.hibernate.InstantiationException: No default constructor for entity: : it.katuiros.model.entities.ExternalRoomManagementPermissions" 




Somehow the exception was launched inside the Hibernate layer and swallowed in the same place, that's why the RollbackException did not bear any cause in itself.

I should post this signalation somewhere else inside this forum?

By adding that default empty constructor to the ExternalRoomManagementPermissions i've managed to make the code work!

Big thanks to Tim Holloway from coderanch, Mabi and James Massey from stackoverflow for the help!


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