3

I have two entities Person and Visit

Person has OneToMany relationship with Visit. I was wondering if I want to save an new entry of Visit, and interm of using RestController. Is my approach correct? Or is there another way which is more efficient?

So I have the following controller which takes a VisitModel from the RequestBody, is it a correct way to call it like so?

VisitModel has the ID of person, and the needed properties for the Visit entity. I use the ID of person to look up in the personRepository for the related Person entry, whereafter I issue it to a new instance of Visit and then use the visitRepository to save it.

@RequestMapping(value="", method=RequestMethod.POST)
public String checkIn(@RequestBody VisitModel visit) {

    Person person = personRepository.findById(visit.personId);

    Visit newVisit = new Visit(visit.getCheckIn, person);
    visitRepository.save(newVisit);

    return "success";
}

The Visit entity looks as following

@Entity
public class Visit {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @JsonProperty("check_in")
    private Date checkIn;

    @JsonProperty("check_out")
    private Date checkOut;

    @ManyToOne
    @JoinColumn(name="personId")
    private Person person;

    public Visit(Date checkIn, Person person) {
        this.checkIn = checkIn;
        this.person = person;
    }

    public Date getCheckIn() {
        return checkIn;
    }

    public void setCheckIn(Date checkIn) {
        this.checkIn = checkIn;
    }

    public Date getCheckOut() {
        return checkOut;
    }

    public void setCheckOut(Date checkOut) {
        this.checkOut = checkOut;
    }

    public Person getPerson() {
        return person;
    }

}

I want to know of the following approach is correct. Or is there another way which is better?

starcorn
  • 8,261
  • 23
  • 83
  • 124

2 Answers2

4

You don't need to get a Person from the database to associate it with a Visit, of course. Because of, you need to have only id of a Person to save it in the foreign key column personId.

If you use JPA EntityManager

  Person person = entityManager.getReference(Person.class, visit.personId);

for Hibernate Session

  Person person = session.load(Person.class, visit.personId);

This methods just create a proxy and don't do any database requests.

With Hibernate Session I used new Person(personId) as @MadhusudanaReddySunnapu suggested. Everything worked fine.

What is the difference between EntityManager.find() and EntityManger.getReference()?

Hibernate: Difference between session.get and session.load

Community
  • 1
  • 1
v.ladynev
  • 19,275
  • 8
  • 46
  • 67
  • When using `new Person(personId)`, it didn't load an entry from database. However it worked well using EntityManager. And with `Session` I couldn't inject it using `@Autowired`. How can I get an instance of session? – starcorn Mar 03 '16 at 20:06
  • @starcorn If you use `EntityManager` — use `getReference()` or `new Person(personId)` (if it works, of course). Don't mix using `EntityManager` and `Session`. To answer your question: you can create a session from `EntityManager` `Session session = entityManager.unwrap(Session.class);` – v.ladynev Mar 04 '16 at 06:10
1

Yes, that seems to me to be the standard way to map a bidirectional relationship. EDIT: The personId column points to the "id" field of the Person entity.Eg:

@Id
private Long id;

UPDATE: 1: The VisitModel is a 'DTO' or Data Transfer Object. Any separate package is fine. You could consider putting them into a separate jar, so that anyone using your API (with java) can use the jar to create the data before making the call. 2) The way you save it is fine as far as I can see.

K.Nicholas
  • 10,956
  • 4
  • 46
  • 66
  • Then in what package would you put `VisitModel`. Right now I have Entity and Repository classes, contained in domain package. But VisitModel doesn't fit into there. – starcorn Mar 03 '16 at 15:05
  • So to save an entry of Visit, you would also do as I did? Look up the Person first with the `personId` and then issue it to a new instance of Visit? – starcorn Mar 03 '16 at 15:09
  • thanks. Didn't knew the DTO was the concept name for it :) – starcorn Mar 03 '16 at 15:26
  • Don't understand, why it should be: _The personId column should be named personId in your Person entity as well, if it is named_ – v.ladynev Mar 03 '16 at 16:41