Hello Jens, You could try using Aries Transaction Control Service => http://aries.apache.org/modules/tx-control/ instead of injecting jpaTemplate
Regards, -Yogesh On Sat, 22 Apr 2017 at 8:38 PM, Jens Offenbach <[email protected]> wrote: > Thanks Christian! That are good news... Especially, your future planning > regarding "TransactionTemplate" sounds really interesting. > > Can you plase provide a small example for your alternative solutions. How > can I obtain a "UserTransaction" to create the transaction? > > Best regards, > Jens > > Gesendet: Samstag, 22. April 2017 um 13:22 Uhr > Von: "Christian Schneider" <[email protected]> > An: [email protected] > Betreff: Re: Consistent entity updates without exposing JpaTemplate > > For now this is a good pattern. I plan to add a pure TransactionTemplate > or similar to cover this case outside of JPATemplate. > > Alternatively you can inject a UserTransaction and use it to create the > transaction. > > Christian > > 2017-04-21 16:49 GMT+02:00 Jens Offenbach <[email protected][mailto: > [email protected]]>:Hallo, > I am sorry, but I am still in trouble with JpaTemplate and API design. I > am trying to hide JpaTemplate in my service implementation, but I am not > sure, if this is the recommended approach. Unfortuantely, I cannot find any > complex examples in the web. > > Let me explain the problem with the help of the TaskService example ( > https://github.com/apache/aries/blob/trunk/jpa/examples/tasklist-ds/src/main/java/org/apache/aries/jpa/example/tasklist/ds/impl/TaskServiceImpl.java[https://github.com/apache/aries/blob/trunk/jpa/examples/tasklist-ds/src/main/java/org/apache/aries/jpa/example/tasklist/ds/impl/TaskServiceImpl.java] > ): > > Task task = taskService.getTask(1); > task.setTitle("New Title#1"); > > Both calls must be done under transaction control to keep the database > consistent (Thanks Christian), so the only correct way would be: > > jpa.tx(em -> { > Task task = taskService.getTask(1); > task.setTitle("New Title#1"); > }); > > The problem is, that service users must have the JpaTemplate reference for > consistent entity updates. The only way to hide JpaTemplate would be to > extend TaskService like this: > > public interface TaskService { > > void tx(Runnable runnable); > > Task getTask(Integer id); > > void addTask(Task task); > > void updateTask(Task task); > > void deleteTask(Integer id); > > Collection<Task> getTasks(); > > } > > @Component > public class TaskServiceImpl implements TaskService { > > @Reference(target = "(osgi.unit.name[http://osgi.unit.name > ]=tasklist)") > private JpaTemplate jpa; > > @Override > public void tx(Runnable runnable) { > jpa.tx(em -> runnable.run()); > } > > } > > The resulting user code that updates an entity consistently (hopefully) > would look like this: > > @Component(immediate = true) > public class TasklistUpdater { > > @Reference > TaskService taskService; > > @Activate > public void addDemoTask() { > if (taskService.getTask(1) == null) { > Task task = new Task(); > task.setId(1); > task.setTitle("Task1"); > taskService.addTask(task); > } > updateDemoTask(); > } > > private void updateDemoTask() { > taskService.tx(() -> { > Task task = taskService.getTask(1); > task.setDescription("A description"); > task.setTitle("A title"); > }); > } > > } > > I am not sure, if this approach works as expected and if JpaTemplate calls > can be nested as shown above. What about overhead? > > Are there any best practices known regarding API design in respect to > JpaTemplate? > > I am thankful for any comments or ideas for improvement? > > Thank you very much, > Jens > > -- > > -- > Christian Schneider > http://www.liquid-reality.de[ > https://owa.talend.com/owa/redir.aspx?C=3aa4083e0c744ae1ba52bd062c5a7e46&URL=http%3a%2f%2fwww.liquid-reality.de > ] > > Open Source Architect > http://www.talend.com[ > https://owa.talend.com/owa/redir.aspx?C=3aa4083e0c744ae1ba52bd062c5a7e46&URL=http%3a%2f%2fwww.talend.com > ] >
