0

I have a Java/Spring web application that runs on Wildfly 10. I configured JPA and was wondering what a common approach is to do update and delete statements. Say for example an httprequest enters the server to show all the details about a Person record. I will use the entity manager to find this record

class PersonDao
{
    @PersistenceContent
    entityManager entityManager

    public Person findPerson(int id)
    {
         assert(id >= 0); //pseudocode

         Person p = this.entityManager.find(Person.class,id);

         assert(p != null); //pseudocode

         return p;
    }
}

Then the details of this person are shown on the screen, the request is finished and the thread gone. The attached Person record in the entity manager is no longer accessible in my code.

Some time later, a new request is launched by the user to update the age of the person. Currently in my Dao class I ualways re-find the record to so I'm sure it's present in my persistence context, but it seems to be redundant and tedious. I would like to know a better way to implement this:

    public void updatePersonAge(int id, int newAge)
    {
         assert(newAge >= 0)

         Person p = this.findPerson(id);

         p.setAge(newAge);

         this.entityManager.persist(p);
    }
Arghavan
  • 1,125
  • 1
  • 11
  • 17
user1884155
  • 3,616
  • 4
  • 55
  • 108
  • persist doesn't work for updates. The call to use is merge(), and probably even that is redundant, JPA tracks changes on managed entities and will automatically synchronize those changes with the database. – Gimby Jan 19 '17 at 16:14

2 Answers2

1

The way I would do this is to create a PersonRepository instead of PersonDao. "Spring Data JPA for more info."

It's simple to learn and awesome once you know it. Your Dao will now just be an interface that queries based on it would look something like...

public interface PersonRepository extends JpaRepository<Person, Integer> { 
    //custom queries here...
}

Even if you put nothing in this file you now have the conviences of create, update, find by id, and delete all from JpaRepository.

I would then create a PersonService to handle the cases described above

@Service
public class PersonService {

    private PersonRepository personRepository        

    @Autowired
    public PersonService(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    // typically you would have create, findById and other methods here

    public void updatePersonAge(int id, int newAge) {
        assert(newAge >= 0)

        Person p = personRepository.findOne(id);

        p.setAge(newAge);

        personRepository.save(p);
   }

   // but if you want an easy way to do this and you can 
   // serialize the whole object instead of just get the id you can
   // simply call and update method
   public Person update(Person person) {
       assert(person.getId() != null);
       return personRepository.save(person);
   }

}

This is assuming you can serialize the object directly with the new age already in the object

Also this may not be the solution you are looking for because I am not directly using an entity manager

  • I really appreciate this input, but after reading the tutorial I think it's too much for me. I'm just new at learning/using JPA, so it's bit too soon to add another layer of abstraction/framework. This is the kind of thing I will look up again after I'm comfortable (or annoyed with the boilerplate) in JPA. Thanks! – user1884155 Jan 19 '17 at 20:47
  • Let me know if you ever want examples! It seems like a lot but it really is easier than you think and learning about different layers isnt too difficult, I typically use a repository (Dao), service (Business logic) , and controller (rest endpoints) pattern. Seems like a lot of abstraction but its nice to separate concerns. I also use Hibernate/JPA to turn the entities directly into DB tables. But if you're still just learning and exploring JPA for personal projects you can ignore what I said. It's easy to get overwhelmed in unfamiliar topics and no need to add unnecessary confusion. – Jack Lazorchak Jan 20 '17 at 02:00
0

The way you do this is correct, calling

Person p = this.findPerson(id);

to get the correct Person object (again) is necessary to update it because as you described the entity manager had no longer access to the Person object.

Nate
  • 11
  • 4