Home > Net >  rest api with spring : Create a new entity based on another one
rest api with spring : Create a new entity based on another one

Time:05-21

I'm new to java and spring. I have two classes

Class 1

class A {
  Long id;
  String attr1;
  String attr2;
 //getters & setters
}

Class 2

class B {
  Long id;
  String attr1;
  String attr2;
  String attr3;
  String attr4;
  @ManyToOne
  A a;
 //getters & setters
}

I want when I call my api by giving the id of an existing object of class A, I'll be able to insert the common attributes to the new object of class B.

Please what's the best way to to do this

what do you think about doing that way ?

@PostMapping("/test/{idObjectA}")
public B createNewB(@PathVariable Long idObjectA, @RequestBody B objectB){
 //verify if ids are null..
 A objectA = aRepository.getAbyId(idObjectA)

 objectB.setAttr1(objectA.getAttr1);
 objectB.setAttr2(objectA.getAttr2);
 objectB.setA(objectA);
 B result = bRepository.save(objectB);
return result; 
}

CodePudding user response:

You said REST, then follow the REST.

From your description, it looks like Object A is a container type and could have multiple instances of A (based on id), e.g. jobs object would have job-id

With that in mind /test/A [HTTP POST] // POST, GET, PUT at container object level

To an item of A

/test/A/{id}  // POST, GET, PUT at container's item level

To create a child resource B of A

/test/A/{id}/B  // POST, GET, PUT at B level (which is a child of A)

Since you used @ManyToOne for B, it seems an instance of A could have multiple child items B

To access B

/test/A/{id}/B

To access an item of B

/test/A/{id}/B/{id}

A real life example of something like this would be:

mycompany/jobs/123/positions/1

Finally a word of note: For most cases, you can use @OneToMany for Entity A (instead of @ManyToOne on entity B), because usually you would need to access child from parent. But if you need to access parent from child too, you could do bidirectional. i.e. use @OneToMany in Entity A and @ManyToOne in Entity B.

Coming to your question about using common properties between Object A and B

Some context first:

You can inherit properties (by same name) form a base entity. For example if you have a "person" as base entity - it could have name, last name, age etc. now an "employee", "manager" etc can inherit from "person". But in this example, person could really be an abstract class since you will create a person entity on its own. See this to learn more.

In a different example, if you have a "children" entity inherited from "parent" - both of these could independently exist and they could have same property names (name, last_name, age etc) - but they will have different data.

In your case it seems you not only want to have same properties for entity A and B, but you actually want to share the same data. That is a wrong design. It is not normalized DB design. You should ideally have no data duplication in DB.

But if you must do that (for some inexplicable reason), you can do something like this (use composition instead of inheritance):

Class SharedData{
   String sharedAttr1;
   String sharedAttr2;
}

Class A{
   SharedData sharedAttributes;
   String attrA1;

   @OneToMany(). // if you want navigation from A to B
   B b;
}

Class B{
   SharedData sharedAttributes;
   String attrB1;
    
   @ManyToOne // if you want navigation from A to B
   @JoinColumn(name="<identity_column_of_A>", nullable=false)
   A a;
}
  • Related