所以我有一个非常基本的结构,我有一个客户端,这个客户端可以有多个地址。
所以在hibernate中我做了类似的事情
@Entity
@Table(name ="tbl_clients")
@Access(value = AccessType.FIELD)
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_client")
private Integer id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "fkIdClientAddress", cascade = CascadeType.ALL)
private List<AddressClient> addressClientList = new ArrayList<>();
另一堂课看起来像这样:
@Entity
@Table(name ="tbl_clients_address")
@Access(value = AccessType.FIELD)
public class AddressClient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_client_address")
private Integer id;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="id_client")
private Client Client;
@Column
private Integer fkIdClientAddress;
将客户端插入具有2个地址的数据库时,它可以工作但数据库中的字段fkIdClientAddress和id_client是空的。所以我不知道地址属于谁。
我该如何解决这个问题?这种结构有什么问题?
第一次改进
类AddressClient
@Entity
@Table(name ="tbl_clients_address")
@Access(value = AccessType.FIELD)
public class AddressClient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_client_address")
private Integer id;
@ManyToOne
@JoinColumn(name="id_client")
private Client client;
班主任
@Entity
@Table(name ="tbl_clients")
@Access(value = AccessType.FIELD)
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_client")
private Integer id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "client", cascade = CascadeType.ALL)
private List<AddressClient> addressClientList = new ArrayList<>();
这看起来更好,但字段id_client仍然为空
当我为每个人创建一个并再次保存AddressClients时,id已成功保存。
@RequestMapping(value = "/addclient",method = RequestMethod.POST)
public void addClient(@AuthenticationPrincipal Principal user,@RequestBody Client client) {
//FIND THE ACTIVE USER
LOGGER.info("SQL: GET PRINCEPAL USER");
User getuser = userDao.findByEmail(user.getName());
for (AddressClient addressClient : client.getAddressClientList())
{
addressClient.setClient(client);
}
clientDao.save(client);
}
答案 0 :(得分:1)
您的映射是错误的。首先,您不需要两个不同的列(id_client
和fkIdClientAddress
)来了解给定地址属于给定客户端。所以要做的第一件事就是删除fkIdClientAddress
。
然后mappedBy
中的OneToMany
属性告诉Hibernate地址中的哪个字段代表拥有ManyToOne
关联。所以必须设置为Client
。 (或者,如果您尊重Java命名约定并将字段重命名为client
,则必须将其设置为client
)。
最后,cascade=ALL
ManyToOne
上的int t[n];
并没有多大意义:当您删除其中一个地址时,您不想删除该客户端。无论如何,这都会失败,因为其他地址仍会引用客户端。
答案 1 :(得分:0)
你的映射是错误的。在Client类中定义集合时,应指明AddressClient类中指向客户端的字段,即字段client
。
@OneToMany(fetch = FetchType.LAZY, mappedBy = "client", cascade = CascadeType.ALL)
private List<AddressClient> addressClientList = new ArrayList<>();
在ClientAddress类中,您有:
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="id_client")
private Client client;
您不需要字段fkIdClientAddress
答案 2 :(得分:0)
在某些情况下,您仍然可以保留列
@Column private Integer fkIdClientAddress;
但您必须为此列设置数据,而不是为
设置值私人客户端客户端;
但这种做法并不恰当。