2015-01-23 2 views
0

У меня есть ряд таблицMapping JPA Сущность

programme  episode   performer  prog_ep_perf 
----------  ---------  ---------  ------------ 
programmeId  episodeId  performerId  programmeId 
progTitle  episodeTitle performerName episodeId 
       programmeId      performerId 

prog_ep_perf является таблицей соединения (programmeId в таблице эпизода может быть излишними из-за столом присоединиться?). Я разработал следующие отношения, которые, я думаю, верны

programme 
    @OneToMany 
    episode  --> One programme can have many episodes 
    @OneToMany 
    performers --> One programme can have many performers 

episode 
    @OneToOne 
    programme --> One episode links to one programme 
    @OneToMany 
    performers --> One episode can have many performers 

performer 
    @OneToMany 
    programme --> One performer can have many programmes 
    @OneToMany 
    episode --> One performer can have many episodes 

Вот как я создал объекты, это правильно?

@Entity 
@Table(name = "PROGRAMME") 
public class Programme { 

    @Id 
    @GeneratedValue(generator="increment") 
    @GenericGenerator(name="increment", strategy="increment") 
    private Long programmeId; 

    private String progTitle; 

    @OneToMany(  
     targetEntity=Performer.class, 
     cascade={CascadeType.PERSIST, CascadeType.MERGE} 
) 
    @JoinTable(
     name="PROG_EP_PERF", 
     [email protected](name="PROGRAMMEID"), 
     inverseJoinColumns={@JoinColumn(name="PERFORMERID")} 
) 
    private Set<Performer> performers; 

    @OneToMany(  
     targetEntity=Performer.class, 
     cascade={CascadeType.PERSIST, CascadeType.MERGE} 
) 
    @JoinTable(
     name="PROG_EP_PERF", 
     [email protected](name="PROGRAMMEID"), 
     inverseJoinColumns={@JoinColumn(name="EPISODEID")} 
) 
    private Set<Episode> episodes; 
} 

@Entity 
@Immutable 
@Table(name = "EPISODE") 
public class Episode { 

    @Id 
    @GeneratedValue(generator="increment") 
    @GenericGenerator(name="increment", strategy="increment") 
    private Long episodeId; 

    @Type(type="com.springtests.model.Programme") 
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinColumn(name="PROGRAMMEID") 
    private Programme programme; 

    private String episodeTitle; 

    @OneToMany(  
     targetEntity=Performer.class, 
     cascade={CascadeType.PERSIST, CascadeType.MERGE} 
) 
    @JoinTable(
     name="PROG_EP_PERF", 
     [email protected](name="EPISODEID"), 
     inverseJoinColumns={@JoinColumn(name="PERFORMERID")} 
) 
    private Set<Performer> performers; 

} 

@Entity 
@Immutable 
@Table(name = "PERFORMER") 
public class Performer { 

    @Id 
    @GeneratedValue(generator="increment") 
    @GenericGenerator(name="increment", strategy="increment") 
    private Long performerId;  

    private String performerName; 

    @OneToMany(  
     cascade = {CascadeType.PERSIST, CascadeType.MERGE}, 
     targetEntity = Programme.class 
) 
    @JoinTable(
     name="PROG_EP_PERF", 
     [email protected](name="PERFORMERID"), 
     inverseJoinColumns={@JoinColumn(name="PROGRAMMEID")} 
) 
    public Set<Programme> programmes; 

    @OneToMany(  
     cascade = {CascadeType.PERSIST, CascadeType.MERGE}, 
     targetEntity = Programme.class 
) 
    @JoinTable(
     name="PROG_EP_PERF", 
     [email protected](name="PERFORMERID"), 
     inverseJoinColumns={@JoinColumn(name="EPISODEID")} 
) 
    public Set<Episode> episodes; 

} 
+0

Вы пробовали это? FYI, этот инструмент может помочь вам: https://github.com/sp00m/db2jpa. – sp00m

+0

Я не думаю, что он будет работать так, как вы могли ожидать, поскольку отображение OneToMany находится между двумя объектами, а не 3. Таким образом, ваши строки таблицы соединений будут иметь только два внешних ключа, заселяемых за раз, и у вас могут быть проблемы со строками отсутствует и т. д., потому что множественные сопоставления записывают и удаляют из одной и той же таблицы способами, которые могут конфликтовать. – Chris

ответ

1

Если таблица является фиксированной и вам просто нужно Entities представить, что в базе данных, то это выглядит как программа имеет OneToMany к эпизоду и эпизод имеет ManyToOne назад к программе, используя поле episode.programmeId как внешний ключ:

public class Programme { 
    .. 
    @OneToMany(mappedby="programme") 
    private Set<Episode> episodes; 
    .. 

public class Episode { 
    .. 
    @ManyToOne 
    @JoinColumn(name = "programmeId") 
    private Programme programme; 
    .. 

в отношениях Episode.programme контролирует внешний ключ в базе данных, это до вас, если вы действительно хотите добавить коллекцию Programme.episodes. Если вы это сделаете, вы должны сохранить его сами, чтобы синхронизировать обе стороны, когда вы вносите изменения. Т.е. JPA не будет автоматически исправлять ссылку на программу, если вы добавите эпизод в коллекцию, а также не добавите эпизод в коллекцию программы, когда вы укажете на нее эпизод.

Что касается таблицы prog_ep_perf, это трехстороннее сопоставление, которое может быть трудно обрабатывать. Если все три внешних ключа должны быть заполнены для каждой строки, тогда он не может быть отображен так, как вы выложили, так как разбивая его на несколько отображений 1: M, один внешний ключ всегда будет нулевым.

Вместо этого лучшим решением является сопоставление таблицы prog_ep_perf как объекта, так что вы можете обрабатывать его точно так, как хотите или нуждаетесь в своем приложении. Альтернативой является использование Карты в качестве типа коллекции с отношениями ManyToMany. См http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Mapping_a_Join_Table_with_Additional_Columns для получения дополнительной информации (JPA 1.0) и для JPA 2,0 см https://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/MapKeyColumns и http://docs.oracle.com/javaee/6/api/javax/persistence/MapKeyJoinColumn.html, но это может выглядеть следующим образом:

public class Programme { 
    .. 
    @ManyToMany 
    @JoinTable(name="prog_ep_perf", 
        [email protected](name="episodeId"), 
        [email protected](name="programmeId")) 
    @MapKeyJoinColumn(name="performerId") 
    Map<Performer, Episode> prog_ep_perf; 
    .. 
} 
Смежные вопросы