jamesdeath123
jamesdeath123

Reputation: 4606

Hibnerate ManyToOne always cascade when it is not asked to

say I have a User table, and a UserRecordInfo table, which saves the action taken to change user's information. for example:

User:

|UserID | UserName|

|1 | test|

and UserRecordInfo:

|UserRecordInfoID | UserID | Action | oldValue | newValue |

| 1 | 1 | update Name | oldTest | test2 |

| 2 | 1 | update Name | test2 | test |

Apparently in Java, when designing Objects, I dont want to have a UserRecordInfo field in User, because there could be hundreds of UserRecordInfo for each user. What I have is:

@Entity
@Table(name="User")
public class User {
private userName;
@Column(name = "userName")
    public String getUserName() {
        System.out.println("getting username");
        return userName;
    }
...
}

and

@Entity
@Table(name="UserRecordInfo")
public class UserRecordInfo {
    private User user;

    @JoinColumn(name = "UserID")  // using javax.persistence.JoinColumn
    @ManyToOne(fetch = FetchType.LAZY) // using javax.persistence.ManyToOne
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

}

The way I create new UserRecordInfo is:

User u = {get user from hibernate}
UserRecordInfo record = new UserRecordInfo();
record.setUser(u);
 .setNewName("test1");
...

Session session = DBSessionHandler.getSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        Serializable result = session.save(record);
        tx.commit();
        return result;
    }
    catch (HibernateException ex) {
        ex.printStackTrace(); 
        if (tx!=null) tx.rollback();
        throw ex;
    }
    finally {
        DBSessionHandler.close();
    }

however it seems like whenever I am inserting a new UserRecordInfo , the User Object always get touched (the println always prints the "getting username"). Why is this happening? am I doing something wrong?

Upvotes: 0

Views: 60

Answers (1)

Shashank Singhal
Shashank Singhal

Reputation: 180

Try putting 'updatable=false' attribute in the the @JoinColumn annotation.

You may want to mark fetch type as 'Eager' for the @ManyToOne annotation.

Also I would recommend that you annotate the fields instead of getters.

The UserRecordInfo class will seem like:

@Entity
@Table(name="UserRecordInfo")
public class UserRecordInfo {

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "UserID", nullable = false, updatable = false)
    @NotNull
    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

Doc for 'updatable' reads as:

(Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider.

which seems to be case you want to solve

Upvotes: 1

Related Questions