Anotação “@JoinTable” do JPA

Nesse caso, você usa a anotação JPA @JoinTable ?

EDIT 2017-04-29 : Como apontado por alguns dos comentadores, o exemplo de JoinTable não precisa do atributo de anotação mappedBy . De fato, versões recentes do Hibernate se recusam a inicializar imprimindo o seguinte erro:

 org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn 

Vamos fingir que você tem uma entidade chamada Project e outra entidade chamada Task e cada projeto pode ter muitas tarefas.

Você pode criar o esquema do database para esse cenário de duas maneiras.

A primeira solução é criar uma tabela chamada Project e outra tabela chamada Task e adicionar uma coluna de chave estrangeira à tabela de tarefas denominada project_id :

 Project Task ------- ---- id id name name project_id 

Dessa forma, será possível determinar o projeto para cada linha na tabela de tarefas. Se você usar essa abordagem, em suas classs de entidade, não precisará de uma tabela de junit:

 @Entity public class Project { @OneToMany(mappedBy = "project") private Collection tasks; } @Entity public class Task { @ManyToOne private Project project; } 

A outra solução é usar uma terceira tabela, por exemplo, Project_Tasks , e armazenar o relacionamento entre projetos e tarefas nessa tabela:

 Project Task Project_Tasks ------- ---- ------------- id id project_id name name task_id 

A tabela Project_Tasks é chamada de “Tabela de associação”. Para implementar esta segunda solução no JPA, você precisa usar a anotação @JoinTable . Por exemplo, para implementar uma associação unidirecional um-para-muitos, podemos definir nossas entidades como tal:

Entidade do Project :

 @Entity public class Project { @Id @GeneratedValue private Long pid; private String name; @JoinTable @OneToMany private List tasks; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getTasks() { return tasks; } public void setTasks(List tasks) { this.tasks = tasks; } } 

Entidade da Task :

 @Entity public class Task { @Id @GeneratedValue private Long tid; private String name; public Long getTid() { return tid; } public void setTid(Long tid) { this.tid = tid; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

Isso criará a seguinte estrutura de database:

Diagrama ER 1

A anotação @JoinTable também permite personalizar vários aspectos da tabela de junit. Por exemplo, anotamos a propriedade de tasks desta forma:

 @JoinTable( name = "MY_JT", joinColumns = @JoinColumn( name = "PROJ_ID", referencedColumnName = "PID" ), inverseJoinColumns = @JoinColumn( name = "TASK_ID", referencedColumnName = "TID" ) ) @OneToMany private List tasks; 

O database resultante teria se tornado:

Diagrama ER 2

Finalmente, se você quiser criar um esquema para uma associação muitos-para-muitos, usar uma tabela de junit é a única solução disponível.

É a única solução para mapear uma associação ManyToMany: você precisa de uma tabela de junit entre as tabelas de entidades para mapear a associação.

Ele também é usado para associações OneToMany (geralmente unidirecionais), quando você não quer adicionar uma chave estrangeira na tabela do lado, e assim mantê-la independente de um lado.

Pesquise @JoinTable na documentação de hibernação para obter explicações e exemplos.

Também é mais limpo usar @JoinTable quando uma entidade pode ser o filho em vários relacionamentos pai / filho com diferentes tipos de pais. Para acompanhar o exemplo de Behrang, imagine que uma Tarefa pode ser filha de Projeto, Pessoa, Departamento, Estudo e Processo.

A tabela de task deve ter 5 campos de chave estrangeira nullable ? Eu acho que não…

Ele permite lidar com muitos para muitos relacionamento. Exemplo:

 Table 1: post post has following columns ____________________ | ID | DATE | |_________|_________| | | | |_________|_________| Table 2: user user has the following columns: ____________________ | ID |NAME | |_________|_________| | | | |_________|_________| 

A tabela de associação permite criar um mapeamento usando:

 @JoinTable( name="USER_POST", joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"), inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID")) 

irá criar uma tabela:

 ____________________ | USER_ID| POST_ID | |_________|_________| | | | |_________|_________|