【问题标题】:JPA: Create multiple parent, single child relationship on GAEJPA:在 GAE 上创建多父、单子关系
【发布时间】:2014-03-14 15:37:01
【问题描述】:

首先,我是一般数据库的新手,所以如果这是一个愚蠢的问题,请在你的答案中提供一些细节,并非常感谢您付出的任何努力!

我在为我的代码设计类结构时遇到了麻烦,我欢迎任何有关此事的建议。我有 3 个数据类

1) 学校

2) 老师

3) 工作坊

学校实体有一个List<Teacher> 和一个List<Workshop> 他们托管。

一个 Workshop Entity 有一个 Host School Entity 和一个 List<Teacher> 的参与者。

一个教师实体有一个List<Workshop> 和一个工作经历List<School>(在下面的代码中没有显示学校列表,因为我要等到以后我先想到更简单的事情,但它是一个目标)

给定城市中的每所学校都将被分配一个条目,仅此而已,教师和研讨会的其他所有内容都必须引用该单个条目。

给定城市中的每一位老师都将被分配到条目/帐户上,仅此而已,因此其他所有内容都必须引用它

我知道我可以使用 ID,但这会涉及大量重复,并且我无法从另一个对象中获取一个对象,条目将是一个 Long 并且即使我制定了自动化整个事情的方法,这会很快耗尽我的查询配额(真的很想避免这种情况)

我希望能够查询单个实体(学校或教师或车间)并能够查看所有其他相关的实体列表。

另外, 教师四处走动,因此我必须能够从一所学校中删除一名教师(作为儿童实体)并将其添加到另一所学校,同时保留哪所学校举办过他们以前的研讨会的记录。

我自己做了这么多

@Entity
public class School 
{
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ID; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy="school")
    private List<Teacher> teachers;

    @OneToMany(cascade = CascadeType.ALL,mappedBy="school")
    private List<Workshop> workshops;
// Getters and Setters and some methods
    }



@Entity
public class Teacher 
{

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @ManyToOne
    private School school;

    private List<Workshop> Workshops;
// Getters and Setters and some methods}

@Entity
public class Workshop
{  
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
    @ManyToOne
    private School school;
    private List<Teacher> Participants;
    // Getters and Setters and some methods}

目前,我可以将尽可能多的教师和研讨会分配给特定的学校实体,但是,我无法将教师实体(已经分配给学校 - 这里的关键点)分配给研讨会。这是我经常遇到的错误

检测到尝试将 Workshop(no-id-yet) 建立为 School(6148469022523392)/Teacher(5585519069102080) 的父级,但由 School(6148469022523392)/Teacher(5585519069102080) 标识的实体已经是 School(614846902225) 的子级)。一旦对象被持久化,就不能建立或更改父对象。

其顺序取决于首先创建和持久化的实体。

非常感谢并等待任何建议和咨询...我不是在寻找完整的解决方案,我只需要有人指出如何做到这一点(我确定我不是第一个被困在这里的人,我相信慷慨的专家会提供帮助)

【问题讨论】:

    标签: java google-app-engine servlets google-cloud-datastore jpa-2.0


    【解决方案1】:

    现在看我有几点:你有三个实体:学校、车间、老师。 学校有一个Tomany - 车间和老师。因此,一旦我们坚持学校,我们将在两个表中都有条目 - 研讨会和教师。而且您还希望 一个研讨会实体有一个托管学校,所以我们在坚持的同时也实现了这一点下面的代码。

    您的学校实体:

    @Entity
    public class School 
    {
        @Id 
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long ID; 
    
        @OneToMany(cascade = CascadeType.PERSIST, mappedBy="school")
        private List<Teacher> teachers;
    
        @OneToMany(cascade = CascadeType.PERSIST,mappedBy="school")
        private List<Workshop> workshops;
    // Getters and Setters and some methods
        }
    

    您的教师实体:

    @Entity
    public class Teacher 
    {
    
        @Id 
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key key;
    
         @ManyToOne(fetch=FetchType.LAZY)
         @JoinColumn(name="key")
        private School school;
    
        // Getters and Setters and some methods}
    

    您的车间实体:

    @Entity
    public class Workshop
    {  
        @Id 
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key key;
    
         @ManyToOne(fetch=FetchType.LAZY)
         @JoinColumn(name="key")
        private School school;
    

    然后:

        em.getTransaction().begin();
     School schoolObj = new School();
     schoolObj.setName("School 1");
     List <Teacher> teachers = new ArrayList<Teacher>();
     List <Workshop> workshopList = new ArrayList<Workshop>();
     Teacher teacher = new Teacher(); 
    teacher.setSchool(schoolObj);
     teacher.setName("Teacher 1");
     teachers.add(teacher);
    Teacher teacher1 = new Teacher();
     teacher1.setSchool(schoolObj); 
    teacher1.setName("Teacher 2"); 
    teachers.add(teacher1); 
    teacher teacher2 = new Teacher();
     teacher2.setSchool(schoolObj);
     teacher2.setName("Teacher 3");
     teachers.add(teacher2); 
    Workshop ws = new Workshop();
    ws.setSchool(schoolObj); //By this you setted schoolObj in workshop entity
    ws.set(some attribute);
    workshopList.add(ws);
    school.setTeachers(teachers); //By this you setted teachers through school ,i.e., entry came in teachers table too.
    school.setWorkshops(workshopList); //By this you setted workshopList through school ,i.e., entry came in workshop table too.
    em.persist(schoolObj); 
    em.getTransaction().commit();
     em.close();
    

    现在您提到了:一个研讨会实体也有一个参与者列表。而一个教师实体有一个他们参加的列表和一个工作经历列表。这表明您在 Workshop 和 Teacher 之间有 ManyToMany。在您的情况下,车间有教师名单,教师也有车间名单。所以在这里,您将需要一个连接表来连接这种多对多关系。同样,在老师和学校之间,您有很多对多,因为两者都有彼此的列表。所以在这里您也需要加入表格。要了解有关此的更多信息,请单击here。 因此,要设置这种多对多关系,您必须通过连接表进行链接,而不是通过在这里持久化,因为它会发生冲突。如果您想根据这种 ManyToMany 关系获取数据,那么您需要进行单独的查询。 希望对您有所帮助!

    【讨论】:

    • 首先,非常感谢您的回复...我已经尝试了几乎所有我能想到的方法,但仍然坚持检测到尝试将 School(6337585022500864) 建立为 School( 6337585022500864)/车间(4930210138947584)/老师(6056110045790208)但学校识别的实体(6337585022500864)/车间(4930210138947584)/老师(6056110045790208)已经是学校的儿童(6337585022500864)/车间(4930210138947584)。一旦对象被持久化,就无法建立或更改父对象。
    • 我不太确定如何使用双向关系来完成它。我的问题是,我希望老师成为某所学校School(6337585022500864) 的孩子,但也成为其他/同一所学校School(6337585022500864)/Workshop(4930210138947584)/Teacher(6056110045790208) 举办的研讨会的孩子...这可以通过ID 数据库和很多轻松完成还有很多方法,但是,我无法查询任何属性值,因为属性只是 ID。我将在下面发布我的 servlet 代码
    • em.getTransaction().begin(); School school = new School(); school.setName("School 1"); List &lt;Teacher&gt;teachers = new ArrayList&lt;Teacher&gt;(); Teacher teacher = new Teacher(); teacher.setName("Teacher 1"); teachers.add(teacher); Teacher teacher1 = new Teacher(); teacher.setName("Teacher 2"); teachers.add(teacher1); teacher teacher2 = new Teacher(); teacher.setName("Teacher 3"); teachers.add(teacher2); Workshop ws = new Workshop(); ws.setParticipants(teachers); school.setTeachers(teachers); List&lt;Workshop&gt;wss = new ArrayList&lt;Workshop&gt;(); wss.add(ws); school.setWorkshops(wss);
    • ` em.persist(school); em.persist(老师); em.persist(teacher1); em.persist(teacher2); em.persist(ws); em.getTransaction().commit(); em.close();`
    • 我猜这个问题会演变成,如何分配访问同一个子实体的多个父分支
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    相关资源
    最近更新 更多