【问题标题】:Delete entity from many to many in jpa在jpa中从多到多删除实体
【发布时间】:2018-02-25 00:11:54
【问题描述】:

我有一个实体

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

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

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "friends")
    private Set<User> friends;
}

目前我通过首先从数据库中获取所有朋友来删除一个朋友,这不是有效/最佳的

@Override
@Transactional
public void deleteFriend(String username, String friend) {
    User user = getUser(username);
    User other = getUser(friend);
    user.getFriends().remove(other);
    other.getFriends().remove(user);
}

由于效率不高,我想使用此查询

public interface UserRepository extends PagingAndSortingRepository<User, Long>{
    void removeByUsernameAndFriendsUsername(String username, String otherUsername);
}

当我尝试使用此查询删除朋友时,出现异常

    Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK8KCUM44FVPUPYW6F5BACCX25C: PUBLIC.COMMENT FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (3)"; SQL statement:
delete from user where id=? and version=? [23503-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:425)
    at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:442)
    at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:317)
    at org.h2.table.Table.fireConstraints(Table.java:980)
    at org.h2.table.Table.fireAfterRow(Table.java:998)
    at org.h2.command.dml.Delete.update(Delete.java:101)
    at org.h2.command.CommandContainer.update(CommandContainer.java:101)
    at org.h2.command.Command.executeUpdate(Command.java:260)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:164)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:150)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
    ... 68 more

你知道是否可以使用@NamedQuery 或@Query 删除它,而我不必先得到所有朋友?类似于下面的查询。

@Query(value = "delete from User U join U.friends friends where U.username = ?1 and friends.username = ?2")

这是评论实体

@Entity
@Table(name="comment")
public class Comment {

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

    @NotNull
    @Size(min=1)
    @Column(name="text", nullable=false)
    private String text;

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

【问题讨论】:

  • 我也遇到过同样的问题,我尝试使用原生 sql,在删除语句中指定了加入表的名称
  • 问题不在查询中。您有一个引用 USER 表的 COMMENT 表,并且如堆栈跟踪中所述,当您尝试删除用户时,您的引用会中断。我怀疑这个问题是一个会被孤立的评论。也发表评论表
  • @Zeromus 评论实体已添加。
  • 如果用户没有 oneToMany 对评论的引用,那么您显然会得到 fk 约束异常。您需要用户级联删除才能发表评论
  • btw FetchType 默认情况下在收集时是惰性的,对单个元素是急切的,因此不必总是指定它

标签: jpa spring-data spring-data-jpa hql jpql


【解决方案1】:

试试:

 @Modifying
 @Query("delete from User U join U.friends friends where U.username = ?1 and friends.username = ?2)
....

【讨论】:

  • @Modifying 没有任何区别,因为查询本身不起作用。还是谢谢。
猜你喜欢
  • 2019-02-11
  • 1970-01-01
  • 2021-08-08
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2019-08-14
相关资源
最近更新 更多