2015-12-16 3 views
2

У меня есть следующий сценарий: Есть компании и сотрудники. У каждой компании есть набор сотрудников. Каждый сотрудник может работать для нескольких компаний. Таким образом, я осуществил следующие соотношения:Hibernate два родителя один ребенок картографирование

Company.class:

@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id")) 
@ManyToMany(fetch = FetchType.LAZY) 
private List<Employee> employees; 

Employee.class:

@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "company_id")) 
@ManyToMany(fetch = FetchType.LAZY) 
private List<Company> companies; 

Очевидно, что работать для нескольких компаний, каждый сотрудник должен иметь несколько не перекрывающихся графиков, присвоенные каждой компании он или она работает. Кроме того, должен быть список расписаний для каждой комбинации Company-Employee, поскольку по истечении срока действия старого расписания, и новый график становится эффективным. Так я и есть Schedule.class, который, как предполагается, имеют child to parent @ManyToOne отношения как к Company и Employee, и должен работать следующим образом: каждый Schedule, и, таким образом, List<Schedule> должны соответствовать точно одной комбинации Company и Employee экземпляров. Как реализовать эти отношения?

Update 1

Я только имею в виду добавление @OneToMany Schedule отношения к каждому Company и Employee, но мне нужно поставить экземпляры Schedule как в Company и Employee каждый раз, и таким образом, просто не посмотрите правильно, и теперь мне не очевидно, как вернуть его обратно. Так что любая помощь будет оценена.


Этот пост был обновлен, чтобы показать сценарий реальной жизни у меня есть, а не только родовые названия Entity1, entity2, Entity3 для классов.

Update 2

Я принял ответ, но я не могу использовать его, если график содержит списки. Согласно моему плану, Schedule должен содержать List<Vacation>, чтобы узнать набор Vacations в течение года и List из Days, каждый из которых показывает начало конкретного дня недели, перерыва и конца этого дня. Эти Days также уникальны для каждого экземпляра Schedule.

Предполагалось, что это что-то вроде ниже, но, очевидно, теперь у меня нет schedule_id, поэтому как соединить эти списки с Schedule?

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) 
@JoinColumn(name = "schedule_id") 
private List<Vacation> vacations; 

@JoinTable(name = "schedule_week", joinColumns = @JoinColumn(name = "schedule_id") , inverseJoinColumns = @JoinColumn(name = "day_id")) 
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) 
private List<Day> week; 

Как включить эти списки?

+0

Было бы лучше, если бы вы добавили реальный сценарий. Решение не может быть связано с спящим режимом, но изменение дизайна. –

+0

@tharindu_DG Я отредактировал свое сообщение, чтобы показать реальный сценарий. Возможно, вы правы, надейтесь, что это сделает вещи более ясными. –

ответ

1

Я хотел бы предложить следующее решение.

Класс embeddable, который содержит Company и Employee для конкретного графика.

@Embeddable 
public class ScheduleOwner implements Serializable{ 

    @MapsId("id") 
    @ManyToOne(cascade = CascadeType.ALL) 
    Company c; 

    @MapsId("id") 
    @ManyToOne(cascade = CascadeType.ALL) 
    Employee e; 
} 

Schedule класс встраивания ScheduleOwner экземпляра.

@Entity 
public class Schedule { 

    @EmbeddedId 
    ScheduleOwner owner; 

    String description; 
} 

Company В и Employee классы (без изменений с ними сделали)

@Entity 
public class Company { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id")) 
    @ManyToMany(fetch = FetchType.LAZY) 
    private List<Employee> employees; 
} 


@Entity 
public class Employee { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "company_id")) 
    @ManyToMany(fetch = FetchType.LAZY) 
    private List<Company> companies; 
} 

UPDATE 1

Ниже, как можно сэкономить и получить результаты.

Employee e1 = new Employee(); 
    Company c1 = new Company(); 
    c1.employees.add(e1); 

    e1.companies.add(c1); 

    ScheduleOwner so = new ScheduleOwner(); 
    so.c = c1; 
    so.e = e1; 

    Schedule s = new Schedule(); 
    s.owner = so; 

    session.save(c1); 
    session.save(e1); 
    session.save(s); 

    // below query will fetch from schedule, where company id = 9 
    Schedule ss = (Schedule) session.createQuery("From Schedule sh where sh.owner.c.id = 9").uniqueResult(); 

ОБНОВЛЕНИЕ 2

@Entity 
public class Company { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id", referencedColumnName="id") 
             , inverseJoinColumns = @JoinColumn(name = "employee_id", referencedColumnName="id")) 
    @ManyToMany(fetch = FetchType.LAZY) 
    List<Employee> employees = new ArrayList<>(); 

    String name; 
} 

@Entity 
public class Employee { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "employees") 
    List<Company> companies = new ArrayList<>(); 

    String name; 
} 

@Entity 
public class Schedule { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    int schedule_id; 

    @ManyToOne 
    @JoinColumn(name = "company_id", insertable = false, updatable = false) 
    private Company company; 
    @ManyToOne 
    @JoinColumn(name = "employee_id", insertable = false, updatable = false) 
    private Employee employee; 

    String description; 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "schedule") 
    List<Vacation> vacations; 

} 

@Entity 
public class Vacation { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int vacation_id; 

    @ManyToOne 
    @JoinColumn(name = "schedule_id") 
    Schedule schedule; 

    @OneToMany(mappedBy = "vacation") 
    List<Day> days; 
} 

Day лицо имеет прямое отношение к Vacation. Не для Schedule.

@Entity 
public class Day { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 


    @ManyToOne 
    @JoinColumn(name = "vacation_id") 
    Vacation vacation; 
} 

Надеюсь, это поможет.

+0

Огромное спасибо за помощь! Я никогда не использовал функцию @ @ Embedded. Не могли бы вы подробнее объяснить, как это должно работать на Java? Правильна ли последовательность действий? установить: создать экземпляр 'Schedule', создать экземпляр' ScheduleOwner' (он не должен иметь свою собственную таблицу в db, как я понимаю), вывести 'Company' и' Employee' из db, установить 'Company' и' Employee' ' ScheduleOwner', установите 'ScheduleOwner' в' Schedule', сохраните 'Schedule' в db. Чтобы получить «расписание» с помощью 'employee_id' и' company_id' - я не понимаю сейчас ... как эта часть должна быть выполнена? Также может быть затронута другая структура приложения? –

+0

Кроме того, если это нужно сделать, почему бы не поместить «Сотрудник» и «Компания» в «Расписание» напрямую с отношениями «@ ManyToOne» (многие «Расписание» с одним «Сотрудником» и с одной «Компанией»), без этот промежуточный класс «ScheduleOwner»? –

+0

@Battle_Slug: Я изменил дизайн и обновил свой ответ. пожалуйста, проверьте. Прочтите это для получения дополнительной информации: http://stackoverflow.com/questions/19341838/why-should-we-use-embeddable-in-hibernate –

Смежные вопросы