我正在將我的應用程序從基於xml的映射遷移到基於JPA註解的映射。但是這隻會在一個簡單的情況下失敗。例如,我有以下3個實體:@OneToMany JPA註釋導致不必要的sql更新,不會級聯
@Entitiy
public class UserAccount {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_account_id", nullable = false,
insertable = true, updatable = false)
@NotNull
private Set<Authority> authorities;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="USER_ID", nullable = false)
... get and setter
}
@Entity
public class Authority {
@Column
private String authority;
... get and setter
}
@Entity
public class User {
... some properties
}
如果我創建一個新的UserAccount實例,並試圖挽救它,我得到了一個例外,因爲管理局實例未保存,這意味着,它不像它應該做的那樣級聯。
org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.TransientObjectException: object references an unsaved transient
instance - save the transient instance before flushing: Authority ...
出現這種情況,因爲Hibernate試圖更新權威行(這是以前沒有插入):我用下面的服務,以節省UserAccount實例
Hibernate:
insert into users ...
Hibernate:
insert into user_accounts ...
Hibernate:
update authorities set user_account_id=? where id=?
。
@Service
public class UserAccountService {
@Resource
private UserAccountRepository userAccountRepository;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void save(UserAccount userAccount) {
userAccountRepository.save(userAccount);
}
}
奇怪的是,該用戶實例將被保存,所以OneToOne映射級聯(如果刪除UserAccount.authorities屬性)。但是,這與基於xml的映射(並且沒有JPA)一起工作。我最終調用了一個單獨的方法來存儲Authoriy實例。
@Service
public class UserAccountService {
@Resource
private UserAccountRepository userAccountRepository;
@Resource
private AuthorityRepository authorityRepository;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void save(UserAccount userAccount) {
userAccountRepository.save(userAccount);
authorityRepository.save(userAccount.getAuthoritiesSet());
}
}
這意味着,我手動級聯......然而,尋找到了執行的SQL語句,我可以看到,休眠插入權威實例,並在此之後,它會更新該行設置UserAccount參考:
Hibernate:
insert into users ...
Hibernate:
insert into user_accounts ...
Hibernate:
insert into authorities (authority) values (?)
Hibernate:
update authorities set user_account_id=? where id=?
對我來說這是一個性能問題,因爲有很多權威機構,我不想有20個插入,之後20個更新。但我無法「刪除」更新,並告訴hibernate將user_account_id與權限一起設置。
因爲我有許多其他對象OneToMany關係,我非常感興趣的是解決這個問題,並感謝您的幫助和想法。
休眠:4.3.4.Final, 彈簧數據的JPA:1.5.1.RELEASE
最好的問候, 丹尼爾
嗨周杰倫,但這正是我已經完成(看看我的UserAccount對象)。這真的很奇怪。 – Phillip
確定嘗試刪除所有父/子映射並逐個添加並檢查問題的起始位置。 – Jay