Reputation: 1710
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
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
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
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