2016-02-27 96 views
0

所以我有一个非常基本的建设,我有一个客户端,这个客户端可以有多个地址。休眠一对多自动插入ID

所以在休眠我做了这样的事情

@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仍然是空

当我创建了一个为每再次保存地址客户端的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); 


} 

回答

1

你的映射是错误的。首先,您不需要两个不同的列(id_clientfkIdClientAddress)就可以知道给定的地址属于给定的客户端。所以首先要做的是删除fkIdClientAddress

然后OneToMany中的mappedBy属性用于告诉Hibernate地址中的哪个字段代表拥有的ManyToOne关联。所以它必须设置为Client。 (或者,如果您遵守Java命名约定并将该字段重命名为client,则必须将其设置为client)。

最后,在ManyToOne上有cascade=ALL没有多大意义:当您删除其中一个地址时,您不想删除客户端。无论如何,这将失败,因为其他地址仍然会引用客户端。

+0

谢谢我更新了你所建议的实体,但是当我查看数据库时,id_client列仍然为空。任何线索我可以忘记? – Greg

+0

您没有发布用于保存客户端及其地址的代码,但我的猜测是您忘记设置地址的客户端字段。这是必需的。 –

+0

你在哪里,我忘了设置客户端。我还添加了保存客户端的RequestMapping是否是正确的方式?或者你会做不同的事情。感谢您分享您的知识。 – Greg

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

0

在某些情况下,你仍然可以保持柱

@Column 私人整数fkIdClientAddress;

但你必须为

私人Client客户端设置此列,而不是设定值数据;

但是这种方法并不合适。