First of all, this solution is no option for me, because I can't change the persistence-unit.
My problem is that I use a JTA EntityManager but I need for exactly one use case something like a transaction:
public boolean saveWithResult(PointsValidityPeriod pointsValidityPeriod)
{
//TODO use transaction here
super.save(pointsValidityPeriod);
if (updatePrevious(pointsValidityPeriod.getValidFrom()) != 1)
{
logger.error("Update of Period was not possible, because UPDATE returned no single result.");
return false;
}
pointsValidityPeriodEvent.fire(pointsValidityPeriod);
return true;
}
Save method (which I can't change):
public void save(T entity)
{
getEntityManager().persist(entity);
}
You see, that there is a save invocation, but this save must be rolled back if the update went wrong, so how can I achieve that? Any ideas?
I have the solution but I don't know why this works. Maybe someone could explain it to me. In my backing bean there is the save method. There are 2 entities. getEntity() is the current entity used by the backing bean, currentValidityPeriod is another instance of that Entity which holds the latest database state of the entity, fetched by currentValidityPeriod = pointsValidityService.findCurrent(); findCurrent() is just a method which executes a TypedQuery:
public PointsValidityPeriod findCurrent()
{
TypedQuery<PointsValidityPeriod> validityPeriodQuery = entityManager.createNamedQuery(PointsValidityPeriod.FindCurrent, PointsValidityPeriod.class);
return validityPeriodQuery.getSingleResult();
}
This is the save method invoked by the view. As you can see, I only pass the current Entity to the service save method. In the previous Entity (currentValidityPeriod), I set another value.
@Override
public void save()
{
Date validFrom = new DateTime(DateTimeZone.forID("Europe/Vienna")).toDate();
getEntity().setValidFrom(validFrom);
currentValidityPeriod.setValidThru(validFrom);
pointsValidityService.save(getEntity());
addSavedSuccessfullyMessage();
}
This is the service method which will be invoked:
@Override
public void save(PointsValidityPeriod pointsValidityPeriod)
{
super.save(pointsValidityPeriod);
}
...and Superclass's save method:
public void save(T entity)
{
getEntityManager().persist(entity);
}
Why does the Entity Manager persist the new Entity and update the old one? I just pass ONE Entity to the Entity Manager. Although this is the expected behavior, I'd like to know why this works.