Pergunta

First I am a newbie with DBs in general so if this turns out to be a dumb question, please be a bit tolerant and generous with details in ur answer and thanks alot for any effort put in to help !!

I am having trouble designing the class structure for my code and will welcome any suggestions concerning the matter. I have 3 data classes

1) School

2) Teacher

3) Workshop

A School Entity has a List<Teacher> and a List<Workshop> they hosted.

A Workshop Entity has a single Host School Entity and a List<Teacher> of participants.

A Teacher Entity had a List<Workshop> they attended and an employment history List<School> (not showing school List in the code below, as I am leaving it till later when I figure simpler things first, but its a target)

Every single school in a given city will be assigned one entry and no more, everything else from Teacher and Workshop has to reference that single Entry.

Every single teacher in a given city will be assigned on entry/ account and no more, so everything else has to reference it

I know I can work with IDs, but that will involve tons of duplication and I wont be able to get an object from within another object, the entry will be a Long and and even if I make methods to automate the whole thing, this will eat up my query quotas very fast( would really love to avoid that)

I would like to be able to query for a single entity(School or Teacher or Workshop) and be able to see all the other Entity Lists associated .

Plus, Teachers move around, so I must be able to remove a Teacher (as a Child Entity) from one School and add it to another, while maintaining the record of which School hosted their previous workshops.

I have done this much on my own

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

Currently I am able to assign as many teachers and workshops to a particular School entity, however, I cannot assign teacher entities (that are already assigned to a School - key point here) to a Workshop. This is the Error I always get

Detected attempt to establish Workshop(no-id-yet) as the parent of School(6148469022523392)/Teacher(5585519069102080) but the entity identified by School(6148469022523392)/Teacher(5585519069102080) is already a child of School(6148469022523392). A parent cannot be established or changed once an object has been persisted.

The order of which is which varies depending on which Entity got created and persisted first.

Thanks alot and awaiting any advice and consultation ... I am not looking for a complete solution, I just need someone to point out how this could be done ( I am sure I am not the first to get stuck here and I am sure that generous experts will help out)

Foi útil?

Solução

Now look I have some points : Three Entites you have : School , Workshop , Teacher. School have oneTomany with - workshop & teacher. So once we are persisting school we'll have entries in both the tables - workshop & teacher.And also you wanted to have A Workshop Entity has a single Host School so we achieved that also while persisting as per below code.

Your School Entity :

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

Your Teacher Entity:

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

Your WorkShop Entity:

@Entity
public class Workshop
{  
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

     @ManyToOne(fetch=FetchType.LAZY)
     @JoinColumn(name="key")
    private School school;

and then :

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

Now you mentioned that: A WorkShop Entity also has a List of participants .And A Teacher Entity had a List they attended and an employment history List. This shows you are having ManyToMany between Workshop & Teacher. As in your case Workshop has List of teachers and Teachers also have List of Workshop's.So here you will be requiring a joining table to lonk this ManyToMany relationship. Similarly, between teacher & school you have ManyToMany as both have List of one other.So here also you will be needing joining table.To learn more about this click here. Hence to set this ManyToMany relationship you have to link through a joining table not by persisting here as it will clash then. And if you want to fetch data as per this ManyToMany relationship then you have make a separate query. Hope this help !

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top