I'm working with Hibernate in a Spring Boot project.
I have the following piece of code:
public class SomeService {
private Dependency dependency;
@Transactional(readOnly=false)
public void doSomething() {
//some BL code...
dependency.doSomeDbManipualation();
someOperation();
}
public void someOperation() {
//some code that eventually fails
}
}
public class Dependency {
public void doSomeDbManipulation() {
Entity entity = ...; //get the entity from current session by its key
if (entity != null) {
session.delete(entity);
}
OtherEntity oEntity = new OtherEntity();
//set its fields
Long oEntityId = session.save(oEntity);
entity = new Entity();
entity.setForeignKey(oEntityId);
//set other fields
session.persist(entity);
}
}
Now, I have in the database an entity with the relevant key. So I expect that when calling the service, the code that looks for the entity will indeed find it. But since someOperation()
fails, I expect to see no change in the DB.
In fact, after calling someService.doSomething()
(and failing), I look in the DB and I see that the existing entity was deleted! But a new entity was not created (which is ok).
Why is this transaction "half committed"?
EDIT:
Apparently delete() and save() are committed immediately. When I debug, I see that entity is immediately deleted after this line in code is done. Also OtherEntity
is added immediately to the DB.
persist() is not committed immediately.
I use AspectJ for transaction management. Here is the relevant part from my pom.xml:
<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>
<forceAjcCompile>true</forceAjcCompile>
<source>1.8</source>
<target>1.8</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.8</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<preserveAllLocals>true</preserveAllLocals>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>AspectJ-Compile</id>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
</project>