Search code examples
javadatabasehibernatefirebirdmyeclipse

Hibernate cascade + composite id's issue


I'm currently learning Hibernate, and I've stumbled into this issue: I have defined 3 entities: User, Module, Permission. Both user and module have a one-to-many relationship with Permission, so that Permission's composite id consists of idUser and idModule. The user class has a property that is a set of Permission's and it is appropriately annotated with @OneToMany, cascade=CascadeType.ALL, etc.

Now, I generated the classes with MyEclipse's reverse engineering feature. The id of permission was created as a separate class that has an idUser and idModule property. I thought I could create a User, add some new permissions to it, and thus saving the user would cascade the operation, and permissions would be saved automatically. This is true except that the operation causes an exception. I run the following code:

Permission p = new Permission();
p.setId(new PermissionId(null, module.getId());
user.getPermissions().add(p);
session.save(user);

The problem I have is that, even though the SQL is being generated correctly (first saves User, then Permission), I get an error from the database driver (Firebird) which states that it can't insert a null value for idUser, which is true, but shouldn't hibernate be passing the newly created user id to the second query?

This particular scenario feels very counter-intuitive to me since I'm inclined to pass a null id to the Permission object since it is new and I want it to be created, but on other hand, I have to set the idModule property since the module already exists, so I don't really understand how an operation like this is supposed to work.

Does anyone know what I'm doing wrong? Thanks


Solution

  • You need to specify a cascade action for Hibernate to perform when you save a User with an attached transient (meaning not-yet-saved) Permission.

    By the way, you might want to consider using a different ID strategy for the Permission object, such as a generated ID value - how can the primary key of the permission row in the database contain a null value?