我在使用多对一关联将JPA实体插入数据库中时遇到问题。
我正在使用:
我正在使用Spring的存储库,那里只有一个保存方法,没有插入,合并或更新方法。
我使用的实体SELECT t1.*, DATEDIFF(t1.date, t3.date) AS Difference
FROM test t1
JOIN (SELECT UniqueId, MAX(Date) AS Date
FROM test
GROUP BY UniqueID) t2 ON t2.UniqueId = t1.UniqueId AND t2.Date = t1.Date
LEFT JOIN test t3 ON t3.UniqueId = t1.UniqueId
AND t3.Date = (SELECT MAX(Date)
FROM test t4
WHERE t4.UniqueId = t3.UniqueId
AND t4.Date < t2.Date)
WHERE DATEDIFF(t1.date, t3.date) >= 10
与另一个实体ID UniqueId Date Difference
T-3 AT-1 2018-04-22 13:05:16 12
T-6 AT-2 2018-05-25 06:09:23 10
具有多对一关联。
如果我用填充DbWatchlist
的字段创建新的DbWatchlistProvider
,一切正常。另外,如果我更改现有的DBWatchlist
,并在此处更改DbWatchlistProvider
的字段并进行保存,则一切正常。
但是,如果我尝试使用现有的DbWatchlist
创建新的DbWatchlistProvider
,则JPA总是尝试为DbWatchlist
插入新记录。
在插入实体DbWatchlistProvider
之前,我尝试从数据库中读取DbWatchlistProvider
,然后进行保存,但是在此还完成了INSERT。这将导致异常:
DbWatchlistProvider
我的代码:
DbWatchlist
在测试中,我尝试了以下操作:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10144 table: WATCHLISTPROVIDER
Error Code: -104
Call: INSERT INTO WatchlistProvider (Key, Description, Id) VALUES (?, ?, ?)
bind => [3 parameters bound]
直到最后一次保存,所有操作均正常进行,并且没有错误,并且与预期的一样。
有人知道问题出在什么地方,为什么要插入@Entity
@Table(name = TableName.WATCHLIST, uniqueConstraints = {
@UniqueConstraint(columnNames = {ColumnName.PROVIDER_KEY, ColumnName.ID})})
@UuidGenerator(name = KEY_GENERATOR)
public class DbWatchlist {
@Id
@Column(name = ColumnName.KEY, nullable = false)
@GeneratedValue(generator = KEY_GENERATOR)
public String key;
@ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = ColumnName.PROVIDER_KEY, nullable = false, updatable = false)
public DbWatchlistProvider watchlistProvider;
@Column(name = ColumnName.ID, nullable = false)
public String id;
@Column(name = ColumnName.DESCRIPTION)
public String description;
@Column(name = ColumnName.LATEST_VERSION)
public String latestVersion;
}
@Entity
@Table(name = TableName.PROVIDER, uniqueConstraints = {
@UniqueConstraint(columnNames = {ColumnName.ID})})
@UuidGenerator(name = KEY_GENERATOR)
public class DbWatchlistProvider {
@Id
@Column(name = ColumnName.KEY, nullable = false)
@GeneratedValue(generator = KEY_GENERATOR)
public String key;
@Column(name = ColumnName.ID, nullable = false)
public String id;
@Column(name = ColumnName.DESCRIPTION)
public String description;
}
@Repository
public interface WatchlistRepository extends CrudRepository<DbWatchlist, String> {
boolean existsByWatchlistProviderAndId(DbWatchlistProvider provider, String id);
}
而不更新吗?
例外是:
DbWatchlistProvider provider = new DbWatchlistProvider();
provider.id = "PROV";
provider.description = "description for provider";
DbWatchlist newRow = new DbWatchlist();
newRow.id = "ID1";
newRow.description = "description";
newRow.watchlistProvider = provider;
DbWatchlist createdRow = repository.save(newRow);
createdRow.description = "update";
createdRow.watchlistProvider.description = "also updated";
createdRow = repository.save(createdRow);
DbWatchlist createdRow2 = new DbWatchlist();
createdRow2.watchlistProvider = createdRow.watchlistProvider;
createdRow2.id = "test";
createdRow2.description = "description";
//This save is not working, but the createdRow2.watchlistProvider.key is filled
repository.save(createdRow2);
答案 0 :(得分:0)
我遇到了同样的问题,最近发现了根本原因。
就我而言,问题是我有两个@Entity
类引用相同的@Table(name = X)
当发生这样的事情时,您必须同时更新两个实体,否则就会收到错误消息,就像在这里看到的一样。
(在我的情况下)解决方案是使用DTO投影,而不是为一个表使用重复的实体。
简单修复,但是错误导致方式混乱,而不是清晰性。
不知道您是否遇到相同的问题,但是您确实有相同的错误。
HTH!