I decided against my original thought of having all this happen automatically. Instead, I created my own "intermediate entity" POJOs that I have allowed JAXB to map to. I will then perform my own JPA lookups and build my actual entity manually. Looking back, this is probably a more proper way to do this since you avoid ambiguity by performing the process by hand.
Can Jersey find a POJO from an ID when mapping from JSON?
-
20-06-2023 - |
Pergunta
It's hard to put this into words, but I'll do my best.
High Level: I am writing a web service to add a new PrblFldr
entity to the database, but I need to associate the proper PrblTmplt
with it (please ignore the terrible naming scheme, I didn't do it). I am POSTing JSON, which Jersey maps to the correct POJOs. But, instead of calling the POJO's constructor for one of the fields, I want it to use the EntityManager
to find the correct object based on an ID.
Low Level: Here's a sample of the JSON I am currently trying to pass to my web service:
{
fldrNm: "test",
prblTmplt: {
tmpltSeqId: 4
}
}
Here's the code on the other side, where the web service sits:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/folders/create")
public Response createFolder(PrblFldr folder) {
em.persist(folder);
return Response.ok(gson.toJson(folder), MediaType.APPLICATION_JSON).build();
}
Now, here's what the PrblFldr
entity looks like, with a lot of irrelevant fields omitted:
@Entity
@Table(name="PRBL_FLDR")
@NamedQuery(name="PrblFldr.findAll", query="SELECT p FROM PrblFldr p")
public class PrblFldr implements Serializable {
@Expose
@Column(name="FLDR_NM")
private String fldrNm;
//bi-directional many-to-one association to PrblTmplt
@Expose
@ManyToOne
@JoinColumn(name="FLDR_TYP_SEQ_ID", insertable=false, updatable=false)
private PrblTmplt prblTmplt;
// other fields...
}
See how that prblTmplt
field is joined on FLDR_TYP_SEQ_ID
? I need to get from that ID to the object. Lastly, here is what our PrblTmplt
class looks like, again with only relevant information included:
@Entity
@Table(name="PRBL_TMPLT")
@NamedQuery(name="PrblTmplt.findAll", query="SELECT p FROM PrblTmplt p")
public class PrblTmplt implements Serializable {
@Expose
@SerializedName("id")
@Id
@Column(name="TMPLT_SEQ_ID")
private long tmpltSeqId;
// other fields...
}
The ultimate goal is to prevent the need for creating some intermediate POJO that Jersey maps to, only to turn right around to fill out the relevant fields in a new PrblFldr
object (and use em.find()
to actually find the PrblTmplt
we're using). I'm not sure if what I'm talking about is possible, but after searching for hours, I figured I would ask you guys.
EDIT: To more clearly specify my situation, the above code (when I log what the web service sends back) outputs JSON like this:
{
fldrNm: "test",
prblTmplt: {
tmpltSeqId: 4
}
}
... which is exactly what I put in. Instead, I want that tmpltSeqId
to be used as a lookup PK to fetch the object that exists with that ID in the DB, so a return might look something like this:
{
fldrNm: "test",
prblTmplt: {
tmpltSeqId: 4,
tmpltDesc: "sample description",
tmpltNm: "sample template name",
// etc...
}
}
Solução