Announcement Announcement Module
Collapse
No announcement yet.
Transaction behavior Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transaction behavior

    Hello all,

    I have a transactional method in my service tier marked using the @transactional annotation:

    Code:
    @Transactional(readOnly=false)
    public void saveEntity(Entity entity) {
       
       if (isEntityValid(entity))  {
              entityDAO.save(entity);
       } else {
              doSomethingElse();
       }
    }
    
    private boolean isEntityValid(Entity entity) {
       // validate the entity and return true or false
    }
    What I want the method to do is to persist the entity into the database *only if* the entity is valid according to some business rules. However, the actual behavior of the method is that, somehow, the entity is being persisted via the DAO even if isEntityValid returns false. I ran the debugger and, for invalid entities, the code did not actually execute the call to entityDAO.save(). However, the query to save the entity is executed looking at the log file, and since the entity is not valid, the application threw some Oracle database exception.

    My question is, why would the the query to save the entity get executed if isEntityValid() returns false? I suspect this has to do with the method being marked as transactional. Also, what do I need to modify such that, if the entity is invalid, the query to save it will not get executed?

    Thanks for any help in advance.

  • #2
    If you're using Hibernate, this behavior appears whenever Hibernate 'thinks' it's necessary to commit some dirty entities it holds in its session.
    I suppose the entity is saved (in logs) was modified before call to saveEntity() method and whatever operations in doSomethingElse() makes Hibernate to flush the changed entity.

    Comment


    • #3
      Thanks Andrei! Your comment about Hibernate persisting dirty objects turned on a light in my head .

      The problem has nothing to do with the method being transactional at all (as I originally thought). What happened was that the entity is a completely new instance (not in database yet). However, I associated it with a parent entity which was already in the database and in the Hibernate session. So even though isEntityValid() returned false and entityDAO.save() did not get invoked, Hibernate was trying to save the parent entity which was dirty. Since I have cascade-save turned on in Hibernate, Hibernate also attempted to save the (child) entity as well while saving the parent entity.

      So my previous code logic was incorrect:
      1) Associate child entity to parent entity.
      2) Validate the child entity and persist it if it's valid.

      To solve the problem I changed my code logic to:

      1) validate (child) entity
      2) if (child) entity is valid, then associate it to parent entity. If it's not valid, then do not associate it to parent entity.
      3) call DAO to save child entity if it's valid

      Thanks so much for your help

      Comment

      Working...
      X