2

I have two entities:

@Entity
@Table(name="\"Group\"")
public class Group implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @NotNull
    @ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER)
    @JoinColumn(name="admin_id", referencedColumnName="id")
    private User admin;
    // .. other properties + setters and getters

}

-

@Entity
@Table(name="User")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin")
    private Set<Group> ownedGroups;
   // other properties + setters and getters
}

This is the repository for the Group entity that extends CrudRepository:

public interface GroupRepository extends CrudRepository<Group, Long> {
    public Group findById(long id);
}

When I delete a group, all groups in the db gets deleted. why does that happen?

This is the what I see in the log (I have the same number of entries in my group table as the number of log lines)

Hibernate: delete from `group` where id=?
Hibernate: delete from `group` where id=?
Hibernate: delete from `group` where id=?
Hibernate: delete from `group` where id=?
Hibernate: delete from `group` where id=?
Hibernate: delete from `group` where id=?

I'm sure that I pass the correct id to the .delete method of the group repository.

Simulant
  • 19,190
  • 8
  • 63
  • 98
Arian
  • 7,397
  • 21
  • 89
  • 177
  • But why calling `groupRepository.delete(id)` delete all the items in the table ? – Arian Jun 09 '17 at 08:07
  • Can you set show_sql in hibernate config and show log that you see when do deletion – xyz Jun 09 '17 at 08:12
  • `Hibernate: delete from `group` where id=?` I put break point on the code and I'm sure that the passed in group id is not `null` or malformed. – Arian Jun 09 '17 at 08:28
  • do you see any delete in sql_log ? is in correct that for example you have 1000 group records in db and after call groupRepository.delete(id) with id=1 all 999 others records are deleted also ??? – xyz Jun 09 '17 at 08:31
  • Any othere delete queries in log – xyz Jun 09 '17 at 10:17
  • @sbjavateam what I see in the log is `delete from group where id=?` – Arian Jun 09 '17 at 17:08
  • Can you remove Cascade.Remove from Group entity and try again? – HRgiger Jun 12 '17 at 20:25

3 Answers3

2

You see Hibernate: delete fromgroupwhere id=? in logs because that's how hibernate logs the queries by default. If you wanna see the parameters bind to the query, increase the logging level of following package log4j.logger.org.hibernate.type=trace here's some more info on this

As for the removing all groups issue, that's caused by

@OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin")
private Set<Group> ownedGroups;

and

@ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER)
@JoinColumn(name="admin_id", referencedColumnName="id")
private User admin;

When you delete group, associated user is deleted by cascade and then all associated groups by another cascade call.

It looks like the User entity is the parent one, as it can have many groups, while the group can belong to only a single user. And it makes sense to remove all User's Groups once it's deleted. So i'd suggest to leave CascadeType.REMOVE only there.

ikryvorotenko
  • 1,393
  • 2
  • 16
  • 27
1

Take a look at the following lines in your code:

@ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER)
@JoinColumn(name="admin_id", referencedColumnName="id")
private User admin;

and these as well:

@OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin")
private Set<Group> ownedGroups;

From what I see I can assume that when deleting a Group you also remove admin of that group. And because you delete the admin - you also removes all the groups that owned by the admin.

It happens because you are using CascadeType.REMOVE in a wrong way. This annotation causes a domino effect when you remove a group. You can read about Cascading in Hibernate here https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html.

I would suggest to you to remove CascadeType.REMOVE as it doesn't seem to fit your domain model very vell. Usually, this type of cascading is useful when you have a strong compositional relation between your entities where child entity doesn't have any sense without its parent. For instance Company and Address. If you remove company it doesn't make any sense to store its address in the database. Your case is an aggregation of entities rather than a composition. Your child entity (Admin) can exist without its parent entity (Group). The same applies to the User and owned groups - if you remove owner of the group it probably doesn't make sense to remove all the owned groups (e.g. because somebody may own it in the future).

Danylo Zatorsky
  • 5,856
  • 2
  • 25
  • 49
0

Parameters by default are displayed as ? by the Hibernate log

See How to print a query string with parameter values when using Hibernate

Just a guess: you remove a Group, it removes its "Admin", that has all Groups that are removed as well. Try to remove CascadeType.REMOVE from the code. Why are you using it ?

Testo Testini
  • 2,200
  • 18
  • 29