ID变成“?”由CrudRepository执行时

时间:2017-06-09 08:01:37

标签: java hibernate

我有两个实体:

@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
}

这是扩展Group的{​​{1}}实体的存储库:

CrudRepository

删除组时,db中的所有组都将被删除。为什么会这样?

这是我在日志中看到的内容(我的组表中的条目数与日志行数相同)

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

我确信我将正确的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=? Hibernate: delete from `group` where id=? 方法。

3 个答案:

答案 0 :(得分:2)

您在日志中看到Hibernate: delete fromwhere id=?,因为这是hibernate默认记录查询的方式。如果您希望参数绑定到查询,请增加以下包的日志记录级别 log4j.logger.org.hibernate.type=trace here's some more info on this

至于删除所有群组问题,这是由

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

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

当您删除组时,关联用户将被级联删除,然后通过另一个级联调用删除所有关联组。

看起来User实体是父实体,因为它可以有多个组,而该组只能属于一个用户。删除后删除所有用户组是有意义的。所以我建议只留下CascadeType.REMOVE

答案 1 :(得分:1)

查看代码中的以下几行:

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

以及这些:

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

从我看到的情况来看,我可以假设在删除组时您也会删除该组的管理员。并且因为您删除了管理员 - 您还会删除管理员拥有的所有组。

之所以会发生这种情况,是因为您以错误的方式使用CascadeType.REMOVE 。删除组时,此注释会导致多米诺骨牌效应。你可以在这里阅读关于Hibernate中的级联https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html

我建议您删除CascadeType.REMOVE,因为它似乎不适合您的域模型。 通常,当您的实体之间存在强大的组合关系时,这种类型的级联很有用,其中子实体没有任何意义而没有父级。例如公司和地址。如果删除公司,将其地址存储在数据库中没有任何意义。您的案例是实体的集合而不是组合。您的子实体(Admin)可以在没有其父实体(Group)的情况下存在。这同样适用于用户和拥有的组 - 如果您删除该组的所有者,则删除所有拥有的组可能没有意义(例如,因为某人可能在将来拥有它)。

答案 2 :(得分:0)

默认情况下,参数由Hibernate日志显示为?

请参阅How to print a query string with parameter values when using Hibernate

只是一个猜测:你删除了一个组,它删除了它的&#34; Admin&#34;,它包含了所有被删除的组。尝试从代码中删除CascadeType.REMOVE。你为什么用它?