I'm using JPA to to link a User to many Devices which can have many remote controls and these can contain many Commands (Buttons like ON / OFF / Change Channel / Volume etc.)
Thus far all my @OneToMany and @ManyToOne relations are working fine and making @GET call to my rest service gives me the Users and all of the devices and all the remotes etc. corresponding to that User, etc.
{
"devices": [{
"deviceName": "Bedroom",
"id": 2,
"remotes": [{
"commands": [{
"commandName": "KEY_1",
"id": 4
},
{
"commandName": "KEY_3",
"id": 7
}],
"id": 6,
"remoteName": "Samsung TV Remote"
},
{
"commands": [{
"commandName": "KEY_4",
"id": 8
},
{
"commandName": "KEY_2",
"id": 5
}],
"id": 3,
"remoteName": "Samsung TV Remote 2"
}]
}],
"id": 1,
"userName": "Cris"}
What I am trying to do is to create all of these at once when POSTing a JSON similair to this to my RESTful Webservice.(Mapping them straight to an Entity without manually parsing it)
{
"userName": "Cris",
"devices": [{
"deviceName": "Bedroom",
"remotes": [{
"remoteName": "Samsung TV Remote",
"commands": [{
"commandName": "KEY_1"
},
{
"commandName": "KEY_2"
}]
},
{
"remoteName": "Samsung TV Remote 2",
"commands": [{
"commandName": "KEY_3"
},
{
"commandName": "KEY_4"
}]
}]
}]}
It creates them but all of the Child entities (Devices, Remotes, Commands) are not mapped to their parent, so their Foreign Keys are not being filled.
Here are my Entities:
Users
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userName;
@OneToMany(mappedBy = "user", fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)
private List<Devices> devices;
Devices
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String deviceName;
@XmlTransient
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID")
private Users user;
@OneToMany(mappedBy = "device", fetch = FetchType.LAZY,cascade=CascadeType.PERSIST)
private List<Remotes> remotes;
Remotes
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String remoteName;
@XmlTransient
@ManyToOne( fetch=FetchType.LAZY)
@JoinColumn(name = "DEVICE_ID")
private Devices device;
@OneToMany(mappedBy = "remote", fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)
private List<Commands> commands;
Commands
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String commandName;
@XmlTransient
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "REMOTE_ID")
private Remotes remote;
POST
@POST
@Override
@Consumes({"application/json"})
public void create(Users entity) {
super.create(entity);
}
Is there a way of automatically mapping the child Entities to their parent after POSTing the JSON or will I need to manually map them to each other ?
Cheers
Ok so it took me a while but It's actually a very simple fix.
All I had to do was set the parent in the child entities when persisting the parent in the @POST method.
Here's an example for adding a device with a remote with commands. I added some try blocks incase any one of these entities didn't actually have a List of Child entities. It might not be the cleanest solution to preventing crashes caused by these certain Exceptions but it's working for what I need it to do.