我得到这个错误,而从一个特定的模式删除一行:
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
即使调用了带有正确参数的delete方法,它仍然在运行插入查询,这会导致数据冲突问题。
模型如下:
@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;
}
}
这是delete方法被调用的地方:
@Override
public void unsubscribeJournalForSubscriber(Journal journal, Account subscriber) {
Subscription subscription = new Subscription();
subscription.setJournalId(journal.getId());
subscription.setUserId(subscriber.getId());
this.subscriptionRepository.delete(subscription);
}
如果你想删除记录而不使用主键,那么创建一个查询。在"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/
删除订阅实体时,只需要设置该实体的"主键",即订阅实体的id
字段。但是,您正在设置journalId
和userId
字段并试图删除。您应该只设置订阅实体的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);
}
}