我正在使用投影介面回傳物體的部分視圖,并且部分視圖包含一組字串。我希望 Set 可以正常作業,但事實并非如此:當我向其中添加新字串時,它會忽略該字串,請參見下面的示例代碼:
@Entity public class MyEntity {
@Id private Long id;
@ElementCollection private Set<String> strings;
// more fields
// getters and setters
}
public interface MyEntityRepo extends CrudRepository<MyEntity, Long> {
MyEntityPartial getMyEntityPartialById(Long id);
}
public interface MyEntityPartial {
Set<String> getStrings();
}
@DataJpaTest public class MyTest {
@Autowired private MyEntityRepo repo;
@BeforeEach private void setup() {
MyEntity myEntity = new MyEntity();
myEntity.setId(1L);
Set<String> strings = new HashSet<>();
strings.add("A");
myEntity.setStrings(strings);
repo.save(myEntity);
}
@Test public void exampleTest() {
MyEntityPartial myEntityPartial = repo.getMyEntityPartialById(1L);
assertThat(myEntityPartial, is(notNullValue()));
assertThat(myEntityPartial.getStrings(), containsInAnyOrder("A"));
myEntityPartial.getStrings().add("B");
assertThat(myEntityPartial.getStrings(), containsInAnyOrder("A", "B"));
}
}
這里測驗在最后一個斷言處失敗,因為myEntityPartial.getStrings()仍然只包含“A”但不包含“A”和“B”。我檢查了Set投影實體myEntityPartial的不是正常HashSet的,而是org.hibernate.collection.internal.PersistentSet. 想知道這是不是問題?以及如何告訴 Hibernate 或 SpringHashSet在投影界面中使用?
uj5u.com熱心網友回復:
注意:我之前沒有在 Spring Data JPA 中使用過預測。所以謝謝你分享這個!:TIL
我認為問題出在myEntityPartial.getStrings().add("B");. 它不會更新實際MyEntity管理的MyRepo. 我猜每次執行都會myEntityPartial.getStrings()回傳資料庫中物體的最新投影。
但是,如果我們存盤myEntityPartial.getStrings()在本地集合中,它就可以作業!
@Test public void exampleTest() {
MyEntityPartial myEntityPartial = repo.getMyEntityPartialById(1L);
Set<String> partialSet = myEntityPartial.getStrings();
assertNotNull(myEntityPartial);
assertTrue(partialSet.contains("A"));
partialSet.add("B");
assertTrue(partialSet.contains("A"));
assertTrue(partialSet.contains("B"));
}
我假設這不是測驗的真正意圖嗎?
因此,如果存盤庫管理的物體被更新,那么它就可以作業
@Test public void exampleTest2() {
MyEntityPartial myEntityPartial = repo.getMyEntityPartialById(1L);
assertNotNull(myEntityPartial);
assertTrue(myEntityPartial.getStrings().contains("A"));
//update the entity in db
updateEntity("B");
assertTrue(myEntityPartial.getStrings().contains("A"));
assertTrue(myEntityPartial.getStrings().contains("B"));
}
/*
* Updating actual entity, returns B with partial projection
*/
private void updateEntity(String newStrings){
MyEntity entity = repo.findById(1L).get();
Set<String> existing = entity.getStrings();
existing.add(newStrings);
entity.setStrings(existing);
repo.save(entity);
}
此外,還myEntityPartial.getStrings()顯示了 LinkedHashSet 型別。
希望這有助于解決問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/477902.html
