如何调试“找到同一集合的两种表示形式”?

2022-09-03 14:31:51

我发现几个关于这个问题的问题,但没有一个对问题的完整解释,以及如何调试它 - 答案都是轶事。

问题是,在 Play 1.2.4 JPA 测试中,当我使用模型时,我遇到了以下异常:save()

org.hibernate.HibernateException:找到同一集合的两种表示形式:模型。职位.项目

我想知道:

  1. 是否有与 Play 无关的一般问题文档?问题处于休眠状态,但Google在这方面的许多结果都在Play应用程序中。
  2. 有哪些基本的最佳做法可以避免此问题?
  3. 这是由游戏引起的吗?还是我做错了什么?
  4. 在我的特定情况下如何解决?

这是github上问题的再现。我有四个实体:

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

还有我的持久性代码:

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

顺便说一句,我尝试按照一个人的建议添加Play关联模块,但它似乎没有帮助。

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

我既有一个表又有一个 ,其中两者都包含相似的字段:包含 a 和 ,而表包含(表示位置 id)、和 。因此,我理解某种意外的冗余是由我的模型定义创建的,但我并不真正了解如何解决它。person_positionposition tableperson_positionPerson_idpositions_idpositionidperson_idcompanies_id

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


答案 1

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

  • 注释上缺少/缺少参数。此参数应接收目标模型中引用回此模型的字段的名称。mappedBy@OneToMany
  • 旧休眠 - 玩 1.2.4 与冬眠 3.6.1 ...升级到3.6.8似乎可以解决另一个这样的问题(只需将以下内容添加到relations.yml,然后播放deps)

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

force: true

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

它实际上是休眠中的一个错误,因为它在持久化对象时被抛出,而它实际上意味着在创建架构时应检测到的“设计时”问题。

我用来调试的步骤:

  • 编写了重现问题的测试
  • 添加了关联模块 - 我不确定它是否解决了问题的一部分,或者使它变得更糟。
  • 通过休眠代码进行调试,并意识到这可能表示休眠问题,而不是用户/配置错误。
  • 注意到Hibernate在3.6.1之后有相当多的错误修复版本,并决定试试我的运气并升级。
  • 同样重要的是,清理tmp文件夹不会有什么坏处 - 在那里播放缓存编译的jars,并且在升级休眠版本等重大更改之后,清理它可能是值得的。

答案 2

尝试

        @OneToMany(mappedBy="position")
        public List<Project> projects;

推荐