如何调试“找到两个相同集合的表示”? [英] How to debug "Found two representations of same collection"?

查看:178
本文介绍了如何调试“找到两个相同集合的表示”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了几个 问题 about ,但没有一个完整地解释了问题,以及如何调试它 - 答案都是轶事。 / p>

问题是在Play 1.2.4 JPA测试中,当我 save()一个模型:


org.hibernate.HibernateException:找到两个相同的表示
集合:models.Position.projects p>

我想知道:


  1. 一般来说,这个问题的文档与Play无关?问题出现在休眠状态,但很多Google的结果都在Play应用程序中。

  2. 避免此问题的一些基本最佳实践是什么?

  3. 是否由Play引起?或者我做错了什么?

  4. 如何解决我的具体情况?

下面是github上的问题复制。我有四个实体:

  @Entity 
public class Person extends Model {
public String name;

@OneToMany(cascade = CascadeType.ALL)
public List< Position>位置;



$实际
公共类位置延伸模型{
public Position(){}
public Position(公司公司){
this.companies =公司;
this.projects = new ArrayList< Project>();
}

@OneToOne
上市公司公司;

@ManyToOne
public Person person;

@OneToMany
public List< Project>项目;
}

@实体
公共类公司扩展模型{
public String name;

$ b $实体
公共类项目扩展模型{
public Project(){}
public Project(String field,String status){
this.theField = field;
this.status = status;
}

@ManyToOne
公共职位;

public String theField;
公共字符串状态;
}

以及我的持久性代码:

 公司Facebook =新公司(); 
facebook.name =Facebook;
facebook.save();
公司twitter =新公司();
twitter.name =Twitter;
twitter.save();

Person joe = new Person();
joe.name =Joe;
joe.save();

joe.positions = new ArrayList< Position>();

位置joeAtFacebook =新位置(脸书);
joeAtFacebook.projects.add(新建项目(Stream,Architect));
joeAtFacebook.projects.add(新项目(Messages,Lead QA));
joe.positions.add(joeAtFacebook);

位置joeAtTwitter =新位置(推特);
joeAtTwitter.projects.add(新项目(从Facebook窃取东西,CEO));
joe.positions.add(joeAtTwitter);
joe.save();

顺便说一句,我尝试添加 Play associations module 作为一个人的建议,它似乎没有帮助。



我看到确实创建的表在某种意义上是重复的:



我有一个 person_position 表和一个位置表,其中都包含相似的字段: person_position 包含 Person_id positions_id ,而位置表包含 id (表示位置id), person_id companies_id 。所以我明白某种意想不到的冗余是由我的模型定义创建的,但我并不真正了解如何解决它。



我认为这可能与双向映射有关,但这里是模型是单向的分支(我删除了一些反向引用) - 问题仍然存在。

解决方案

据我所知,错误是由以下任何组合引起的:




  • @OneToMany 注释中缺少/缺少 mappedBy 参数。此参数应接收目标模型中引用该模型的字段的名称。

  • 旧的休眠 - Play 1.2.4随附hibernate 3.6.1 ...升级到3.6 .8似乎解决了另一个这样的问题(只需将以下内容添加到dependencies.yml,并发挥重要作用)



- org.hibernate - > hibernate-core 3.6.8.Final:



force:true



对于我来说,上述步骤解决了这个问题

它实际上是hibernate中的一个bug,因为它在持久化对象时被抛出,而实际上这意味着创建模式时应该检测到的设计时间问题。

我用来调试的步骤:


  • 写了一个测试,问题

  • 添加了关联模块 - 我不是确定它是否解决了问题的一部分,或者变得更糟。

  • 通过hibernate代码进行调试,并意识到这可能表示休眠问题,而不是用户/配置错误。 >
  • 注意到hibernate在3.6.1之后有很多bug修复版本,并且决定尝试我的运气并升级。

  • 同样重要的是,清理tmp文件夹可以''''''''''''''''''''''''''''''''''''''''''''''受伤 - 在缓存中编译jar文件,并且在升级hibernate版本之类的重大更改之后,清理它可能是值得的。

    I have found several questions about this, but none with a complete explaintation of the problem, and how to debug it - the answers are all anecdotal.

    The problem is that in a Play 1.2.4 JPA test, I'm getting this exception when I save() a model:

    org.hibernate.HibernateException: Found two representations of same collection: models.Position.projects

    I would like to know:

    1. Is there a documentation of this problem in general, unrelated to Play? The issue is in hibernate, yet a lot of the Google results on this are within Play apps.
    2. What are some basic best practices to avoid this problem?
    3. Is it caused by Play? Or something I'm doing wrong?
    4. How to resolve in my specific case?

    Here is a reproduction of the problem on github. I have four entities:

    @Entity
    public class Person extends Model {
        public String name;
    
        @OneToMany(cascade = CascadeType.ALL)
        public List<Position> positions;
    }
    
    
    @Entity
    public class Position extends Model {
        public Position(){}
        public Position(Company companies) {
            this.companies = companies;
            this.projects = new ArrayList<Project>();
        }
    
        @OneToOne
        public Company companies;
    
        @ManyToOne
        public Person person;
    
        @OneToMany
        public List<Project> projects;
    }
    
    @Entity
    public class Company extends Model {
        public String name;
    }
    
    @Entity
    public class Project extends Model {
        public Project(){}
        public Project(String field, String status){
            this.theField = field;
            this.status = status;
        }
    
        @ManyToOne
        public Position position;
    
        public String theField;
        public String status;
    }
    

    And my persistence code:

    Company facebook = new Company();
    facebook.name = "Facebook";
    facebook.save();
    Company twitter = new Company();
    twitter.name = "Twitter";
    twitter.save();
    
    Person joe = new Person();
    joe.name = "Joe";
    joe.save();
    
    joe.positions = new ArrayList<Position>();
    
    Position joeAtFacebook = new Position(facebook);
    joeAtFacebook.projects.add(new Project("Stream", "Architect"));
    joeAtFacebook.projects.add(new Project("Messages", "Lead QA"));
    joe.positions.add(joeAtFacebook);
    
    Position joeAtTwitter = new Position(twitter);
    joeAtTwitter.projects.add(new Project("Steal stuff from Facebook", "CEO"));
    joe.positions.add(joeAtTwitter);
    joe.save();
    

    BTW, I've tried adding the Play associations module as one person suggested, and it does't seem to help.

    I see that indeed that tables that are created are duplicate in a sense:

    I have both a person_position table and a position table, where both contain similar fields: person_position contains a Person_id and positions_id, while the position table contain id (meaning position id), person_id, and companies_id. So I understand some kind of unintended redundancy is created by my model definition, but I don't really understand how to solve it.

    I thought this might be related to bi-directional mappings, but here is a branch where the model is uni-directional (I removed some back-references) - and the problem still occurs.

    解决方案

    As far as I've been able to tell, the error is caused by any combination of:

    • Lacking / missing mappedBy parameter on @OneToMany annotations. This parameter should receive the name of the field in the target model that refers back to this model.
    • Old hibernate - Play 1.2.4 ships with hibernate 3.6.1 ... upgrading to 3.6.8 seems to resolve another such issue (just add the following to dependencies.yml, and play deps)

    - org.hibernate -> hibernate-core 3.6.8.Final:

    force: true

    For me, the above steps solved the issue.

    It is in fact a bug in hibernate, because it is thrown when persisting objects, while it actually implies a "design time" problem that should be detected when creating the schema.

    Steps I used to debug:

    • Wrote a test that reproduced the problem
    • Added the associations module - I'm not sure if it resolved a part of the issue, or made it worse.
    • Debugged through hibernate code, and realized this probably indicates a hibernate problem, not a user / configuration error.
    • Noticed that hibernate has quite a few bugfix versions after 3.6.1, and decided to try my luck and upgrade.
    • Also important, cleaning the tmp folder can't hurt - Play caches compiled jars there, and after a major change like upgrading hibernate version, it might be worthwhile to clean it.

    这篇关于如何调试“找到两个相同集合的表示”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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