2016-02-27 98 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客戶端設置此列,而不是設定值數據;

但是這種方法並不合適。