我有一個類,有幾個懶惰的初始化收藏,OneToMany
和ManyToMany
。 ManyToMany
關係是單向的,因此Expert
類沒有Project
集合。ManyToMany收藏不斷被刪除
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "project")
private List<Logging> loggings = new ArrayList<Logging>();
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "project_expert", joinColumns = { @JoinColumn(name = "project") }, inverseJoinColumns = { @JoinColumn(name = "expert") })
private List<Expert> experts = new ArrayList<Expert>();
public void add(Logging logging) {
logging.setProject(this);
this.loggings.add(logging);
}
public void add(Expert expert) {
this.experts.add(expert);
}
對象添加到OneToMany
集合,我這樣做:
Project project = projectService.save(projectForm.getProject());
Logging logging = new Logging();
project.add(logging);
logging = loggingService.save(logging);
這工作得很好。然而,當我嘗試的元素添加到ManyToMany
,那麼這個集合似乎在保存父對象被刪除了,所以我不能添加多個子對象:
@RequestMapping(value="/newexpert", method=RequestMethod.POST)
public String newExpert(@ModelAttribute("projectForm") ProjectForm projectForm, BindingResult result, ModelMap model) {
Project project = projectService.save(projectForm.getProject());
Expert expert = projectForm.getExpert();
if (expert != null) {
project.add(expert);
}
project = projectService.save(project);
return "redirect:/project/" + project.getId();
}
這是什麼服務方法看起來像(projectRepository
擴展PagingAndSortingRepository
):
@Override
@Transactional
public Project save(Project project) {
return projectRepository.save(project);
}
在日誌中,我發現這一點:
2014-05-01 17:01:49 DEBUG AbstractCollectionPersister:1174 - Deleting collection: [test.model.Project.experts#1]
2014-05-01 17:01:49 DEBUG SQL:109 - delete from project_expert where project=?
2014-05-01 17:01:49 DEBUG AbstractCollectionPersister:1232 - Done deleting collection
編輯1:這是在save(projectForm.getProject())
會發生什麼:
2014-05-01 18:30:04 DEBUG Loader:2136 - Loading entity: [test.model.Project#1]
2014-05-01 18:30:04 DEBUG SQL:109 - select project0_.id as id1_4_1_, ... from Project project0_ left outer join project_expert experts1_ on project0_.id=experts1_.project left outer join Expert expert2_ on experts1_.expert=expert2_.id where project0_.id=?
2014-05-01 18:30:04 DEBUG Loader:951 - Result set row: 0
2014-05-01 18:30:04 DEBUG Loader:1485 - Result row: EntityKey[test.model.Expert#2], EntityKey[test.model.Project#1]
2014-05-01 18:30:04 DEBUG Loader:1305 - Found row of collection: [test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:160 - Resolving associations for [test.model.Project#1]
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:286 - Done materializing entity [test.model.Project#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:232 - 1 collections were found in result set for role: test.model.Project.experts
2014-05-01 18:30:04 DEBUG CollectionLoadContext:280 - Collection fully initialized: [test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:240 - 1 collections initialized for role: test.model.Project.experts
2014-05-01 18:30:04 DEBUG Loader:2160 - Done entity load
2014-05-01 18:30:04 DEBUG AbstractTransactionImpl:175 - committing
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:149 - Processing flush-time cascades
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:189 - Dirty checking collections
2014-05-01 18:30:04 DEBUG CollectionEntry:202 - Collection dirty: [test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG CollectionEntry:202 - Collection dirty: [test.model.Project.parties#1]
2014-05-01 18:30:04 DEBUG CollectionEntry:202 - Collection dirty: [test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG Collections:194 - Collection found: [test.model.Project.experts#1], was: [test.model.Project.experts#1] (initialized)
2014-05-01 18:30:04 DEBUG Collections:201 - Collection found: [test.model.Project.loggings#1], was: [test.model.Project.loggings#1] (uninitialized)
2014-05-01 18:30:04 DEBUG Collections:201 - Collection found: [test.model.Project.parties#1], was: [test.model.Project.parties#1] (uninitialized)
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:123 - Flushed: 0 insertions, 0 updates, 0 deletions to 3 objects
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:130 - Flushed: 0 (re)creations, 3 updates, 0 removals to 3 collections
2014-05-01 18:30:04 DEBUG EntityPrinter:114 - Listing entities:
2014-05-01 18:30:04 DEBUG EntityPrinter:121 - test.model.Expert{id=2, ...}
2014-05-01 18:30:04 DEBUG EntityPrinter:121 - test.model.Project{..., id=1, ...}
2014-05-01 18:30:04 DEBUG EntityPrinter:121 - test.model.Expert{id=1, ...}
2014-05-01 18:30:04 DEBUG SQL:109 - select count(id) from Logging where project_id =?
2014-05-01 18:30:04 DEBUG SQL:109 - select count(id) from Party where project_id =?
2014-05-01 18:30:04 DEBUG AbstractCollectionPersister:1174 - Deleting collection: [test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG SQL:109 - delete from project_expert where project=?
2014-05-01 18:30:04 DEBUG AbstractCollectionPersister:1232 - Done deleting collection
2014-05-01 18:30:04 DEBUG JdbcTransaction:113 - committed JDBC Connection
2014-05-01 18:30:04 DEBUG JdbcTransaction:126 - re-enabling autocommit
...
2014-05-01 18:30:04 DEBUG AbstractLoadPlanBasedCollectionInitializer:88 - Loading collection: [test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG SQL:109 - select loggings0_.project_id as project_5_4_0_, loggings0_.id as id1_2_0_, ... from Logging loggings0_ where loggings0_.project_id=?
2014-05-01 18:30:04 DEBUG ResultSetProcessorImpl:168 - Preparing collection intializer : [test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG ResultSetProcessorImpl:127 - Starting ResultSet row #0
2014-05-01 18:30:04 DEBUG CollectionReferenceInitializerImpl:77 - Found row of collection: [test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:160 - Resolving associations for [test.model.Logging#1]
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:286 - Done materializing entity [test.model.Logging#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:232 - 1 collections were found in result set for role: test.model.Project.loggings
2014-05-01 18:30:04 DEBUG CollectionLoadContext:280 - Collection fully initialized: [test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:240 - 1 collections initialized for role: test.model.Project.loggings
2014-05-01 18:30:04 DEBUG AbstractLoadPlanBasedCollectionInitializer:118 - Done loading collection
編輯2:顯然,ManyToMany
集合中的父對象projectForm.getProject()
初始化而空。怎麼可能?我期望它是單元化的,或者如果它由於某種原因被初始化,不是空的?
您能否顯示'Project'類的'add'方法?這是一種多態的方法,可以採用Logging或Expert這個參數,對吧?和'projectService.save()'。 –
我已經編輯了我的帖子。 – user3170702
將FetchType.LAZY更改爲FetchType.EAGER,並查看它是否至少在getProject()中提供了值。如果將該對象聲明爲lazily加載,Hibernate將初始化一個空集合,直到嘗試使用它時纔會填充它。 – JamesENL