【问题标题】:Could not execute statement; SQL [n/a]; constraint [null];无法执行语句; SQL [不适用];约束[空];
【发布时间】:2017-01-11 00:01:08
【问题描述】:

我在从特定架构中删除一行时收到此错误:

Hibernate: select journal0_.id as id1_2_0_, journal0_.content as content2_2_0_, journal0_.filename as filename3_2_0_, journal0_.subject as subject4_2_0_, journal0_.tags as tags5_2_0_, journal0_.user_id as user_id6_2_0_, journal0_.version as version7_2_0_ from journal journal0_ where journal0_.id=?
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into subscription (journal_id, user_id, version, id) values (?, ?, ?, ?)
2016-09-03 01:08:01.581  WARN 13462 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 23505, SQLState: 23505
2016-09-03 01:08:01.581 ERROR 13462 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : Unique index or primary key violation: "UK_9XFQUT5UKXNSBX8NL2LR23TC5_INDEX_9 ON PUBLIC.SUBSCRIPTION(USER_ID, JOURNAL_ID) VALUES (9, 2, 10)"; SQL statement:
insert into subscription (journal_id, user_id, version, id) values (?, ?, ?, ?) [23505-191]
2016-09-03 01:08:01.598  INFO 13462 --- [nio-8080-exec-9] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements
2016-09-03 01:08:01.632 ERROR 13462 --- [nio-8080-exec-9] c.j.exceptions.ErrorController           : Exception during execution of SpringSecurity application

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

即使调用了带有正确参数的删除方法,它仍在运行导致数据违规问题的插入查询。

这是模型:

@Entity
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"userId", "journalId"})})
public class Subscription {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Version
    private Integer version;

    private Integer userId;
    private Integer journalId;

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return this.id;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public Integer getVersion() {
        return this.version;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getUserId() {
        return this.userId;
    }

    public void setJournalId(Integer journalId) {
        this.journalId = journalId;
    }

    public Integer getJournalId() {
        return this.journalId;
    }
}

这是调用删除方法的地方:

@Override
public void unsubscribeJournalForSubscriber(Journal journal, Account subscriber) {

    Subscription subscription = new Subscription();
    subscription.setJournalId(journal.getId());
    subscription.setUserId(subscriber.getId());


    this.subscriptionRepository.delete(subscription);
}

【问题讨论】:

  • “即使调用了带有正确参数的删除方法……” -- 证据在哪里?我看到两个选择和一个插入,没有删除。
  • 我的意思是 delete 方法与正确的参数一起使用,但插入查询仍然完成而不是 delete 。怎么会?
  • 您是否已将代码单步执行到调用delete 方法的地步?你确定代码正在执行吗?
  • 是肯定代码正在执行。

标签: java sql hibernate spring-boot


【解决方案1】:

删除订阅实体,只需要设置实体的主键,即订阅实体的id字段。但是,您正在设置 journalIduserId 字段并尝试删除。 您应该只设置订阅实体的id 字段,它将被删除。

更新:

您的存储库代码应该是

public interface SubscriptionRepository extends CrudRepository<Subscription, Integer> {

    /**
     * Returns array of Subscribed journals by specific user's id
     * 
     * @param userId
     * @return
     */
    ArrayList<Subscription> findByUserId(Integer userId);
    List<Subscription> findByUserIdAndJournalId(Integer userId, Integer journalId);

}

现在您的企业登录代码将是:

@Override
public void unsubscribeJournalForSubscriber(Journal journal, Account subscriber) {

    List<Subscription> list = subscriptionRepository.findByUserIdAndJournalId(subscriber.getId(), journal.getId());

    for(Subscription subscription : list){
        subscriptionRepository.delete(subscription);
    }

}

【讨论】:

  • id 是自动生成属性。那么如何在不先查询 id 的情况下做到这一点。
  • id 自动生成并在插入实体时设置。如果要删除,您需要设置用于删除该特定实体的 id。如果你之前不知道,那么你应该先查找然后删除。
  • 有什么方法可以使用 journal_id 和 subscription_id 删除吗?
【解决方案2】:

如果您想在不使用主键的情况下删除记录,请为此创建查询。在“SubscriptionRepository”中创建一个名为

的方法

@Modifying @Query("delete from Subscription s where s.role. userId = ?1 and s. journalId = ?2") deleteByUserIdJournalId(Integer userId,Integer journalId) 然后使用该方法删除您的记录。 关注这个https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

【讨论】:

    猜你喜欢
    • 2019-07-24
    • 2020-02-12
    • 2019-06-06
    • 1970-01-01
    • 2018-07-07
    • 2019-11-15
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多