ManyToMany收藏不断被删除 [英] ManyToMany collection keeps getting deleted

查看:105
本文介绍了ManyToMany收藏不断被删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有几个懒惰初始化集合的类,它们都是 OneToMany ManyToMany ManyToMany 关系是单向的,所以 Expert 类没有项目 collection。

  @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy =project)
私人清单<记录> 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(专家级专家){
this.experts.add(expert);
}

将一个对象添加到 OneToMany collection,我会这样做:

  Project project = projectService.save(projectForm.getProject()); 
记录日志记录= new Logging();
project.add(logging);
logging = loggingService.save(logging);

这很好。但是,当我尝试向 ManyToMany 集合添加元素时,集合似乎在保存父对象时被删除,所以我永远不能添加多个子对象:

  @RequestMapping(value =/ newexpert,method = RequestMethod.POST)
public String newExpert(@ModelAttribute (projectForm)ProjectForm projectForm,BindingResult结果,ModelMap模型){

Project project = projectService.save(projectForm.getProject());
Expert expert = projectForm.getExpert();
if(expert!= null){
project.add(expert);
}
project = projectService.save(project);

returnredirect:/ project /+ project.getId();

$ / code>

这就是服务方法的样子( projectRepository extends PagingAndSortingRepository ):

  @Override 
@Transactional
public Project save(Project project){
return projectRepository.save(project);
}

在日志中我找到了这个:

  2014-05-01 17:01:49 DEBUG AbstractCollectionPersister:1174  - 删除集合:[test.model.Project.experts#1] 
2014- 05-01 17:01:49 DEBUG SQL:109 - 从project_expert中删除where project =?
2014-05-01 17:01:49 DEBUG AbstractCollectionPersister:1232 - 完成删除集合

Edit 1:这就是 save(projectForm.getProject())所发生的情况:

  2014-05-01 18:30:04 DEBUG加载器:2136  - 加载实体:[test.model.Project#1] 
2014-05-01 18: 30:04 DEBUG SQL:109 - 选择project0_.id作为id1_4_1_,...从项目project0_左外部连接project_expert experts1_ on project0_.id = experts1_.project left outer join专家expert2_在experts1_.expert = expert2_.id其中project0_。 ID =?
2014-05-01 18:30:04 DEBUG加载程序:951 - 结果集行:0
2014-05-01 18:30:04 DEBUG加载程序:1485 - 结果行:EntityKey [test。 model.Expert#2],EntityKey [test.model.Project#1]
2014-05-01 18:30:04 DEBUG加载程序:1305 - 找到一行集合:[test.model.Project.experts# 1]
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:160 - 解决[test.model.Project#1]的关联
2014-05-01 18:30:04 DEBUG TwoPhaseLoad: 286 - 完成实体化[test.model.Project#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:在结果集中为角色找到232个 - 1个集合:test.model.Project.experts
2014-05-01 18:30:04 DEBUG CollectionLoadContext:280 - 完全初始化集合:[test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext :初始化为角色的240 - 1个集合:test.model.Project.experts
2014-05-01 18:30:04 DEBUG加载器:2160 - 完成实体加载
2014-05-01 18:30 :04 DEBUG AbstractTransactionImpl:175 - 提交
2 014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:149 - 处理刷新时间级联
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:189 - 脏检查集合
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作品集:194 - 作品集:[test.model.Project.experts#1],是:[test.model.Project.experts#1](初始化)
2014-05-01 18:30:04 DEBUG作品集:201 - 发现作品集:[test.model.Project.loggings#1]:[test.model.Project.loggings#1](未初始化)
2014-05-01 18:30:04 DEBUG集合:201 - 找到集合:[test.model.Project.parties#1],是:[test.model.Project.parties#1](未初始化)
2014-05-01 18:30:04调试AbstractFlushingEventLi stener:123 - 刷新:0插入,0更新,0删除3个对象
2014-05-01 18:30:04 DEBUG AbstractFlushingEventListener:130 - 刷新:0(重新创建),3更新,0清除3个集合
2014-05-01 18:30:04 DEBUG EntityPrinter:114 - 上市实体:
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 )来自Logging where project_id =?
2014-05-01 18:30:04 DEBUG SQL:109 - 从派对选择计数(ID)where project_id =?
2014-05-01 18:30:04 DEBUG AbstractCollectionPersister:1174 - 删除集合:[test.model.Project.experts#1]
2014-05-01 18:30:04 DEBUG SQL: 109 - 从project_expert中删除where project =?
2014-05-01 18:30:04 DEBUG AbstractCollectionPersister:1232 - 完成删除集合
2014-05-01 18:30:04 DEBUG JdbcTransaction:113 - 提交的JDBC连接
2014- 05-01 18:30:04 DEBUG JdbcTransaction:126 - 重新启用autocommit
...
2014-05-01 18:30:04 DEBUG AbstractLoadPlanBasedCollectionInitializer:88 - 加载集合:[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 - 准备集合intializer:[test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG ResultSetProcessorImpl :127 - 开始的ResultSet行#0
2014-05-01 18:30:04 DEBUG CollectionReferenceInitializerImpl:77 - 找到一行集合:[test.model.Project.loggings#1]
2014-05 -01 18:30:04 DEBUG TwoPhaseLoad:160 - 解决[test.model.Logging#1]的关联
2014-05-01 18:30:04 DEBUG TwoPhaseLoad:286 - 完成实体化[test.model .Logging#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:在角色结果集中找到232个集合:test.model.Project.loggings
2014-05-01 18:30:04 DEBUG CollectionLoadContext:280 - 完全初始化的集合:[test.model.Project.loggings#1]
2014-05-01 18:30:04 DEBUG CollectionLoadContext:240 - 1为角色初始化的集合: test.model.Project.loggings
2014-05-01 18:30:04 DEBUG AbstractLoadPlanBasedCollectionInitializer:118 - D一个加载集合

编辑2:显然父对象 projectForm.getProject()中的ManyToMany 集合被初始化并为空。怎么可能?我希望它是单元化的,或者如果它是由于某种原因初始化的,而不是空的?

解决方案

在您的服务中创建一个方法像这样:

  @Transactional 
public Project addExperts(Project project,List< Expert> experts){
列出< Expert> projectExperts = project.getExperts(); (专家专家:专家)
{
projectExperts.add(专家);
}

project.setExperts(projectExperts);
返回项目;
}

这将封装在Transaction中的Project.experts的提取,以便延迟加载的集合可以被正确提取并初始化。通过添加您在控制器中确定的列表,然后可以正确保存项目并使级联创建新的专家对象。如果您没有看到 INSERT 语句创建您的 code> Expert 对象,那就是你的问题。如果数据库中不存在对 Expert 对象的引用,那么Hibernate不能在 JoinTable 中插入引用,因此为什么它会删除你的集合对象。


I have a class with several lazily initialized collections, both OneToMany and ManyToMany. The ManyToMany relationship is unidirectional, so the Expert class has no Project collection.

@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);
}

To add an object to a OneToMany collection, I would do this:

Project project = projectService.save(projectForm.getProject());
Logging logging = new Logging();
project.add(logging);
logging = loggingService.save(logging);

This works fine. However, when I try to add an element to the ManyToMany collection, the collection seems to be deleted upon saving the parent object, so I can never add more than one child object:

@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();
}

This is what the service method looks like (projectRepository extends PagingAndSortingRepository):

@Override
@Transactional
public Project save(Project project) {
    return projectRepository.save(project);
}

In the logs I found this:

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

Edit 1: This is what happens upon 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

Edit 2: Apparently the ManyToMany collection in the parent object projectForm.getProject() is initialized and empty. How can that be? I expect it to be unitialized, or if it is initialized for some reason, not empty?

解决方案

Create a method in your service like this:

@Transactional
public Project addExperts(Project project, List<Expert> experts){
    List<Expert> projectExperts = project.getExperts();
    for(Expert expert: experts){
        projectExperts.add(expert);
    }

    project.setExperts(projectExperts);
    return project;
}

This will encapsulate the fetching of Project.experts inside a Transaction so that the lazily loaded collection can be fetched and initialised properly. By adding the list you have determined in your controller, you can then save the project properly and have the cascade create the new expert objects. I'm pretty sure this should fix your problem.

If you don't see INSERT statements creating your Expert objects, then thats your problem. Hibernate can't insert a reference to your Expert objects into your JoinTable if they don't exist in the database, hence why it would delete your collection object.

这篇关于ManyToMany收藏不断被删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆