Greg
Greg

Reputation: 1710

Hibernate one to many automatically insert id

So i have a very basic construction where i have a client and this client could have multiple addresses.

So in hibernate i did something like this

@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<>();

And the other class looks like this :

@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;

When inserting a client into the database who has 2 addresses it works but the fields fkIdClientAddress and id_client is are empty in the database. So i have no idea to who the address belong.

How can i fix this? And what is wrong with this construction?

first improvements

Class 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;

Class 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<>();

This is looking better but the field id_client is still null

When i created a for each and save the AddressClients again the id is successful saved.

@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);


}

Upvotes: 0

Views: 2095

Answers (3)

Tinh Cao
Tinh Cao

Reputation: 67

In some cases, you still can keep column

@Column private Integer fkIdClientAddress;

But you have to set data for this column instead of setting value for

private Client client;

But this approach is not appropriate.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691765

Your mapping is wrong. First of all, you don't need two different columns (id_client and fkIdClientAddress) to know that a given address belongs to a given client. So the first thing to do is to remove fkIdClientAddress.

Then the mappedBy attribute in OneToMany is usd to tell Hibernate which field in address represents the owning ManyToOne association. So it must be set to Client. (or, if you respect the Java naming conventions and rename the field to client, it must be set to client).

Finally, having cascade=ALL on a ManyToOne doesn't make much sense: you don't want to delete the client when you delete one of its addresses. That would fail anyway, since other addresses would still reference the client.

Upvotes: 1

iullianr
iullianr

Reputation: 1284

Your mappings are wrong. When you define the collection in Client class, you should indicate the field in the AddressClient class which points back to the Client and that is the field client.

@OneToMany(fetch = FetchType.LAZY, mappedBy = "client", cascade = CascadeType.ALL)
private List<AddressClient> addressClientList = new ArrayList<>();

And in ClientAddress class you have:

@ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_client")
    private Client client;

You do not need the field fkIdClientAddress

Upvotes: 0

Related Questions