Как правильно работать с отношениями FK с JPA - PullRequest
0 голосов
/ 06 мая 2019

У меня есть эта диаграмма отношений сущностей прямо здесь: https://i.imgur.com/V05i6nK.png

И я пытаюсь сделать этот проект. Я сделал все занятия, установил отношения и все остальное.

Но как только я попытался запустить и создать нового пользователя, я получаю сообщение об ошибке ниже:

Внешний ключ (FK3w0xeq6jk6vt2vi1fydpci0y9: T_PAGAMENTO [CD_CORRIDA])) должен иметь такое же количество столбцов, что и первичный ключ, на который ссылаются (T_CORRIDA [CD_PASSAGEIRO, CD_MOTORISTA, CD_CORRIDA])

Я пытался настроить эти отношения, но у меня ничего не получилось.

@Entity
@Table(name="T_CORRIDA")
@SequenceGenerator(name="sq_corrida", sequenceName="SEQ_T_CORRIDA", allocationSize=1)
public class Corrida {

    @Id
    @GeneratedValue(generator="sq_corrida", strategy = GenerationType.SEQUENCE)
    @Column(name="CD_CORRIDA")
    private int cd_corrida;

    @Column(name="DS_ORIGEM", length = 150, nullable= false)
    private String ds_origem;

    @Column(name="DS_DESTINO", length= 150, nullable= false)
    private String ds_destino;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="DT_CORRIDA")
    private Calendar dt_corrida;

    @Column(name="VL_CORRIDA", nullable= false)
    private float vl_corrida;

    @Id
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="CD_MOTORISTA")
    private Motorista motorista;

    @Id
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="CD_PASSAGEIRO")
    private Passageiro passageiro;

    @OneToMany(mappedBy="corrida", cascade= CascadeType.PERSIST)
    private List<Pagamento> listaPagamento;
@Entity
@Table(name="T_MOTORISTA")
@SecondaryTable(name="T_DADOS_MOTORISTA", pkJoinColumns={@PrimaryKeyJoinColumn(name="NR_CARTEIRA")})
public class Motorista {

    @Id
    @Column(name="NR_CARTEIRA", nullable= false)
    private int nr_carteira;

    @Column(name="NM_MOTORISTA", length= 150, nullable= false)
    private String nm_motorista;

    @Temporal(TemporalType.DATE)
    @Column(name="DT_NASC")
    private Calendar dt_nasc;

    @Lob
    @Column(name="FT_CARTEIRA")
    private byte[] ft_carteira;

    @Enumerated(EnumType.STRING)
    @Column(name="DS_GENERO")
    private TipoSexo ds_genero;

    @ManyToMany(cascade=CascadeType.PERSIST)
    @JoinTable(name="T_VEICULO_MOTORISTA", 
        joinColumns=@JoinColumn(name="NR_CARTEIRA"), 
        inverseJoinColumns=@JoinColumn(name="CD_VEICULO"))
    private List<Veiculo> listaVeiculo;

    @OneToMany(mappedBy="motorista")
    private List<Corrida> corridasMotorista;

    @Column(name="NR_BANCO", table="T_DADOS_MOTORISTA")
    private int banco;

    @Column(name="NR_AGENCIA", table="T_DADOS_MOTORISTA")
    private int agencia;

    @Column(name="NR_CONTA", table="T_DADOS_MOTORISTA")
    private int conta;
@Entity
@Table(name="T_PASSAGEIRO")
@SequenceGenerator(name="seq_passageiro", sequenceName="SEQ_T_PASSAGEIRO", allocationSize=1)
public class Passageiro {

    @Id
    @Column(name="cd_passageiro")
    @GeneratedValue(generator="seq_passageiro", strategy=GenerationType.SEQUENCE)
    private int cd_passageiro;

    @Column(name="NM_PASSAGEIRO", nullable= false, length= 100)
    private String nm_passageiro;

    @Temporal(TemporalType.DATE)
    @Column(name="DT_NASCIMENTO", nullable=false)
    private Calendar dt_nascimento;

    @Enumerated(EnumType.STRING)
    @Column(name="DS_GENERO")
    private TipoSexo ds_genero;

    @OneToMany(mappedBy="passageiro")
    private List<Corrida> corridaPassageiro;
@Entity
@Table(name="T_PAGAMENTO")
@SequenceGenerator(name="seq_pgto", sequenceName="SEQ_T_PGTO", allocationSize=1)
public class Pagamento {

    @Id
    @Column(name="CD_PAGAMENTO", nullable= false)
    @GeneratedValue(generator="seq_pgto", strategy=GenerationType.SEQUENCE)
    private int cd_pagamento;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="DT_PAGAMENTO", nullable= false)
    private Calendar dt_pagamento;

    @Column(name="VL_PAGAMENTO", nullable= false)
    private float vl_pagamento;

    @Enumerated(EnumType.STRING)
    @Column(name="DS_PAGAMENTO", nullable = false)
    private TipoPagamento ds_forma_pagamento;

    @ManyToOne
    @JoinColumn(name="CD_CORRIDA")
    private Corrida corrida;

Я просто хочу знать, что я делаю неправильно и почему я получаю ошибку внешнего ключа, как правильно настроить эти ключи. Заранее спасибо!

1 Ответ

1 голос
/ 07 мая 2019

Добавляя аннотацию @Id в поля cd_corrida, motorista и cd_corrida, вы указали, что у сущности Corrida есть составной PK.В этом случае Pagamento должен указать объединение в соответствующих 3 столбцах таблицы T_PAGAMENTO.

Однако, так как вы используете автоматически сгенерированную последовательность для одного из полей @ID в Corrida, нет необходимости иметь составной PK, так как Corrida может быть однозначно идентифицирована только этим полем:

@Id
@GeneratedValue(generator="sq_corrida", strategy = GenerationType.SEQUENCE)
@Column(name="CD_CORRIDA")
private int cd_corrida;

Затем вы можете удалить другие 2 @Id аннотации.Нет необходимости в том, чтобы идентификатор совпадал с какой-либо базой данных, определенной в столбцах PK: он просто должен быть уникальным, и, указав последовательность для cd_corrida, он может использоваться в качестве идентификатора Entity Manager.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...