我正在嘗試使用 JPA 映射大型資料庫的某些列,以便從中獲取一些資料。該資料庫具有復合主鍵,其中一些也是外鍵。我對 JPA 映射相當陌生,所以我需要一些幫助。這是我得到的錯誤:
org.hibernate.tool.schema.spi.CommandAcceptanceException:通過 JDBC 陳述句執行 DDL“更改表 tbpedidoentrega 添加約束 FKiwjj63py270eqhfb1olp08oox 外鍵(fk_cliente)參考 tbcadastro”時出錯
并且:
錯誤:外鍵的參考列數和被參考列數不一致
JPA 似乎沒有在命令末尾指定它需要參考的列(正確的命令應該是alter table tbpedidoentrega add constraint FKiwjj63py270eqhfb1olp08oox foreign key (fk_cliente) references tbcadastro (codigo)
),只指定了表。但為什么?
這是我的代碼:客戶端類
package com.agilsistemas.construtordepedidos.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "tbcadastro")
public class ClienteModel implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "codigo")
int idCliente;
@Column(name = "razao")
String razaoSocial;
@Column(name = "logradouro")
String rua;
@Column(name = "numero")
String numero;
@Column(name = "bairro")
String bairro;
@Column(name = "complemento")
String complemento;
@Column(name = "cidade")
String cidade;
@Column(name = "fixo")
String telefoneFixo;
@Column(name = "celular")
String celular;
@Column(name = "cliente")
String cliente;
}
訂單類:
package com.agilsistemas.construtordepedidos.model;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "tbpedidoentrega")
public class PedidoModel implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_pedido", nullable = false)
@SequenceGenerator(name = "sqpedido")
int idPedido;
@Column(name = "data_pedido", nullable = false)
LocalDate dataPedido;
@Column(name = "hora_pedido", nullable = false)
LocalDate horaPedido;
@ManyToOne
@JoinColumn(name = "fk_funcionario")
FuncionarioModel fkFuncionario;
@ManyToOne
@JoinColumn(name = "fk_cliente")
ClienteModel fkCliente;
@OneToMany(mappedBy = "pedido")
List<ItemPedidoModel> itensPedido;
}
我期待這會創建 FK 并啟動后端。我認為問題在于hibernate生成的SQL命令的末尾(應該是references tbcadastro (codigo)
),但我不知道它為什么會這樣生成。
uj5u.com熱心網友回復:
經過一些干預和一些研究,我能夠解決這個問題。問題是表 Cliente 有一個復合主鍵,所以我需要實作一個特殊的類來指定復合鍵:
package com.agilsistemas.construtordepedidos.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Embeddable
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
public class IdClienteModel implements Serializable {
@Column(name = "codigo")
private int idCliente;
@ManyToOne
@JoinColumn(name = "empresa")
private EmpresaModel idEmpresa;
}
然后我像這樣實作了 ClienteModel 類:
package com.agilsistemas.construtordepedidos.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "tbcadastro")
public class ClienteModel implements Serializable {
@EmbeddedId
private IdClienteModel idCliente; //using the object as the ID
@Column(name = "razao")
String razaoSocial;
@Column(name = "logradouro")
String rua;
@Column(name = "numero")
String numero;
@Column(name = "bairro")
String bairro;
@Column(name = "complemento")
String complemento;
@Column(name = "cidade")
String cidade;
@Column(name = "fixo")
String telefoneFixo;
@Column(name = "celular")
String celular;
@Column(name = "cliente")
String cliente;
}
現在,在 Pedido (Order) 類中,我可以得到這樣的 OneToOne 關系:
@OneToOne
@JoinColumns({
@JoinColumn(name = "fk_cliente", referencedColumnName = "codigo", insertable = false, updatable = false),
@JoinColumn(name = "fk_empresa", referencedColumnName = "empresa", insertable = false, updatable = false) })
ClienteModel fkCliente;
我對所有其他具有復合 PK 的物體也這樣做了,現在應用程式可以正常啟動。我希望這個遮陽篷可以幫助別人。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/529369.html