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...