java - way - spring boot one to many unidirectional




Qual é a diferença entre @JoinColumn e mappedBy ao usar uma associação JPA @OneToMany? (4)

A anotação @JoinColumn indica que essa entidade é a proprietária do relacionamento (ou seja: a tabela correspondente tem uma coluna com uma chave estrangeira para a tabela referenciada), enquanto o atributo mappedBy indica que a entidade deste lado é o inverso do relacionamento e o proprietário reside na "outra" entidade. Isso também significa que você pode acessar a outra tabela da classe que anotou com "mappedBy" (relacionamento totalmente bidirecional).

Em particular, para o código na pergunta, as anotações corretas ficariam assim:

@Entity
public class Company {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
    private List<Branch> branches;
}

@Entity
public class Branch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "companyId")
    private Company company;
}

Qual é a diferença entre:

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
    @JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
    private List<Branch> branches;
    ...
}

e

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")
    private List<Branch> branches;
    ...
}

A anotação mapeadaPor ideal, deve sempre ser usada no lado pai (classe da empresa) do relacionamento bidirecional, nesse caso, deve estar na classe Empresa apontando para a variável de membro 'company' da classe Child (classe Branch)

A anotação @JoinColumn é usada para especificar uma coluna mapeada para unir uma associação de entidade, esta anotação pode ser usada em qualquer classe (Pai ou Filho), mas idealmente deve ser usada apenas em um lado (na classe pai ou na classe Child, não em ambos) aqui, neste caso, usei-o no lado Child (classe Branch) da relação bidirecional indicando a chave estrangeira na classe Branch.

abaixo está o exemplo de trabalho:

classe pai, companhia

@Entity
public class Company {


    private int companyId;
    private String companyName;
    private List<Branch> branches;

    @Id
    @GeneratedValue
    @Column(name="COMPANY_ID")
    public int getCompanyId() {
        return companyId;
    }

    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }

    @Column(name="COMPANY_NAME")
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="company")
    public List<Branch> getBranches() {
        return branches;
    }

    public void setBranches(List<Branch> branches) {
        this.branches = branches;
    }


}

classe de criança, Branch

@Entity
public class Branch {

    private int branchId;
    private String branchName;
    private Company company;

    @Id
    @GeneratedValue
    @Column(name="BRANCH_ID")
    public int getBranchId() {
        return branchId;
    }

    public void setBranchId(int branchId) {
        this.branchId = branchId;
    }

    @Column(name="BRANCH_NAME")
    public String getBranchName() {
        return branchName;
    }

    public void setBranchName(String branchName) {
        this.branchName = branchName;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="COMPANY_ID")
    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }


}

Gostaria apenas de acrescentar que o @JoinColumn nem sempre precisa estar relacionado ao local da informação física, como sugere this resposta. Você pode combinar @JoinColumn com @OneToMany mesmo se a tabela pai não tiver dados de tabela apontando para a tabela filho.

Como definir um relacionamento OneToMany unidirecional no JPA

OneToMany unidirecional, sem ManyToOne inversa, sem tabela de associação

Parece estar disponível apenas no JPA 2.x+ . É útil para situações em que você deseja que a classe filha contenha apenas o ID do pai, não uma referência completa.


Não concordo com a resposta aceita aqui por Óscar López. Essa resposta é imprecisa!

NÃO é @JoinColumn que indica que essa entidade é a proprietária do relacionamento. Em vez disso, é a anotação @ManyToOne que faz isso (em seu exemplo).

As anotações de relacionamento, como @OneToMany , @OneToMany e @ManyToMany informam ao JPA / Hibernate para criar um mapeamento. Por padrão, isso é feito por meio de uma tabela de junção separada.


@JoinColumn

O objetivo de @JoinColumn é criar uma coluna de junção se ainda não existir uma. Em caso afirmativo, essa anotação pode ser usada para nomear a coluna de junção.


MappedBy

A finalidade do parâmetro MappedBy é instruir o JPA: NÃO crie outra tabela de junção, pois o relacionamento já está sendo mapeado pela entidade oposta desse relacionamento.



Lembre-se: MappedBy é uma propriedade das anotações de relacionamento cuja finalidade é gerar um mecanismo para relacionar duas entidades que, por padrão, criam uma tabela de junção. MappedBy interrompe esse processo em uma direção.

MappedBy se que a entidade que não usa o MappedBy é a proprietária do relacionamento, pois a mecânica do mapeamento é ditada em sua classe por meio do uso de uma das três anotações de mapeamento no campo de chave estrangeira. Isso não apenas especifica a natureza do mapeamento, mas também instrui a criação de uma tabela de junção. Além disso, a opção para suprimir a tabela de junção também existe aplicando a anotação @JoinColumn sobre a chave estrangeira que a mantém dentro da tabela da entidade proprietária.

Então, em resumo: @JoinColumn cria uma nova coluna de junção ou renomeia uma existente; enquanto o parâmetro MappedBy trabalha colaborativamente com as anotações de relacionamento da outra classe (child) para criar um mapeamento através de uma tabela de junção ou criando uma coluna de chave estrangeira na tabela associada da entidade proprietária.

Para ilustrar como o MapppedBy funciona, considere o código abaixo. Se o parâmetro MappedBy fosse deletado, o Hibernate criaria duas tabelas de junção! Por quê? Porque existe uma simetria em relacionamentos muitos-para-muitos e o Hibernate não tem nenhuma razão para selecionar uma direção sobre a outra.

Nós, portanto, usamos o MappedBy para dizer ao Hibernate, nós escolhemos a outra entidade para ditar o mapeamento do relacionamento entre as duas entidades.

@Entity
public class Driver {
    @ManyToMany(mappedBy = "drivers")
    private List<Cars> cars;
}

@Entity
public class Cars {
    @ManyToMany
    private List<Drivers> drivers;
}

Adicionar @JoinColumn (name = "driverID") na classe proprietária (veja abaixo), impedirá a criação de uma tabela de junção e, em vez disso, criará uma coluna de chave estrangeira driverID na tabela Cars para construir um mapeamento:

@Entity
public class Driver {
    @ManyToMany(mappedBy = "drivers")
    private List<Cars> cars;
}

@Entity
public class Cars {
    @ManyToMany
    @JoinColumn(name = "driverID")
    private List<Drivers> drivers;
}




one-to-many