adam bien's blog

RoR persistency vs. JPA (Java SE/EE5) - or what is easier? 📎

I got an interesting comment from sam (thank you)  probably from RoR space. It explains how the inconsistencies are solved using versioning INSIDE a transaction:

Ruby On Rails code::

begin
   Employee.transaction do
     emp = Employee.new
     emp.name = 'Kurz'
     emp.surname = 'Martin'
     emp.save!
     emp2 = Employee.find(emp.id)
     emp3 = Employee.find(emp.id)
     emp2.surname = 'Marta'
     emp3.name = 'Hürlimann'
     puts "before emp2.save!"
     emp2.save!
     puts "before emp3.save!"
     emp3.save!
     emp.reload
     pp emp
     raise "Rollback"
   end
rescue
    puts $!
  end

==> Attempted to update a stale object

----------

I could not resist and wrote the same functionality with CMP 2.1:

---EJB 2.1 ----

EmployeRemote employee = serviceLocator.getHome().findByPrimaryKey(vo.getId());
employee.setName("Kurz");
employee.setSurname("Martin");
//no saving needed
EmployeRemote employee2 = employeHome.findByPrimaryKey(vo.getId());
EmployeRemote employee3 = employeHome.findByPrimaryKey(vo.getId());
employee2.setSurname("Marta");
employee2.setName("Hürlimann");

Inconsistencies not possible: Reason: employee == employee2 == employee3 (you get always the same instance back)

I also provided a Java Persistence API (JPA) implementation. Public fields are used, but setters were also possible:


---Entity 3.0 (Java EE 5) ---

EntityManager em; // will be injected by container

Employe employee = em.find(Employee.class,employee.getId());
employee.name  = "Kurz";  // setters are also possible
employee.surname = "Martin";

//no saving needed
Employe employee2 = em.find(Employee.class,employee.getId());
Employe´employee3 = em.find(Employee.class,employee.getId());
employee2.surname = "Marta";
employee2.name = "Hürlimann";

...also here: inconsistencies not possible: Reason: employee == employee2 == employee3 (you get always the same instance back)...

And now the interesting question: which implementation is more compact, expressive and easier to understand? :-) The Java EE container cares about transactions, and consistency, so no save and transaction control operations are needed. Also the exception: ==> Attempted to update a stale object cannot happen and you have not to care about this stuff. Things become more interesting in case you are changing some objects in a graph and not only attributes :-).

ActiveRecord is great, but you have to know what you are doing and it is not always easier than OR-mapping...