0

In hibernate I have created a one-to-many relationship between user and roles. More then one user can be associated with a role, but a user can be associated with just one role.

In User class, I have

            @ManyToOne
            @JoinColumn(name = "role_id")
            private Role role_id;

In Role Class, I have

    @OneToMany(mappedBy="role_id", fetch=FetchType.LAZY)
    private Collection<User> userList = new ArrayList<User>();

If I am saving a new user as :

{
"userName" : "Michael",
"role_id" : {
              "id" : 8    
            }
}

It saves user even when role table has no role with id as 8( and no entry is done in role table). I want that I should get a referential integrity error whenever I am saving a user with a non existent role. What should I change?

My Users table is created as:

CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) DEFAULT NULL,
  `mobile` varchar(255) DEFAULT NULL,
  `username` varchar(255) NOT NULL,
  `role_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_abcdef` (`role_id`),
  CONSTRAINT `FK_abcdef` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
anik
  • 155
  • 1
  • 17

2 Answers2

0

Do you have FK constraint in your tables in the database? Maybe this if you use mySql can help you. Or alternatively you can set the restriction in your database by your own.

  • 1
    Thanks loannis, but I have foreign key constraint set. Please see the updated answer – anik Jul 25 '17 at 10:46
0

In your @OneToMany annotation you probably need to add targetEntity = User.class. That is because of the following reasons:

  1. java generics use type erasure, which means that in the generated bytecode, your userList is of type Collection, not of type Collection<User>. So, hibernate has no clue what the target entity is, unless you explicitly tell it.

  2. Hibernate generally likes to follow a silent error / hidden error approach, which means that it silently ignores problems the moment they happen (as for example the moment where it has no clue what type your collection elements are) and to fail later, when the cause of the problem is not very clear anymore. (As for example when you execute a query which should fail, and it doesn't, or you execute a query which should fetch something, and it fetches nothing.)

  3. As of java 9, the compiler does actually store information about the actual type arguments used when creating generic fields within the generated .class files, and it is possible to discover that information using reflection, but I am not aware of hibernate having been updated to check this information.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • JPA specifications requires `targetEntity` only for raw collections, it should be able to get generic types. I believe it is not required. – fg78nc Jul 25 '17 at 11:02
  • @fg78nc if that's right, I will delete my answer. But I believe that this is what made it work for me in the past, and I see plenty of code that uses `targetEntity` without raw collections, so I certainly hope that the OP gives it a try. – Mike Nakis Jul 25 '17 at 11:37
  • I just stated that `targetEntity` purpose is for raw collections as per specs. If it worked for you, that is fine, let him try. – fg78nc Jul 25 '17 at 11:40