Reputation: 41
I am building a spring boot back-end and want to make a rest end-point, that deletes all item by the suppliers id. When I call the rest end-point, I get 'no entitymanager with actual transaction available' exception.
How can I fix this error?
I tried the @Transactional
annutation, but the error still occurs
Model:
public class Item {
public Item() {}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ItemId")
private int id;
public int getId() {
return this.id;
}
public void setId(int Id) {
this.id = Id;
}
@Column(name = "Suppid")
private int suppid;
public int getSuppid() {
return this.suppid;
}
public void setSuppid(int Suppid) {
this.suppid = Suppid;
}
}
Repository:
public interface ItemRepository extends CrudRepository<Item, Integer> {
@Transactional
public void deleteAllBySuppid(int suppid);
}
Controller:
public void deleteSupplier(@RequestParam(name = "suppid") int suppid) {
itemrepo.deleteAllBySuppid(suppid);
supprepo.delete(supprepo.findByid(suppid));
}
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.0.Final</version>
</dependency>
</dependencies>
I expect the item to be deleted, but it throws:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call] with root cause
Upvotes: 2
Views: 21962
Reputation: 314
I also faced this issue, but the the @Transactional
annotation didn't solve it.
I had a strange problem: I didn't add @SpringBootApplication
to my Main class. Adding this annotation solved my problem.
Upvotes: 0
Reputation: 14875
To explain why @Transactional
is needed:
Whan you look at the CrudMethodMetadataPostProcessor.postProcess
method, all Methods contained in the implementations
set are called with the TransactionSynchronizationManager
. Custum Functions need to add Transactions manually.
Upvotes: 3
Reputation: 41
Ok, it was my mistake, because I put the @Transactional
at the wrong place. I had to put the annutation on the method in my controller, not in the CrudRepository.
Repository:
public interface ItemRepository extends CrudRepository<Item, Integer> {
public void deleteAllBySuppid(int suppid);
}
Controller:
@Transactional
public void deleteSupplier(@RequestParam(name = "suppid") int suppid) {
itemrepo.deleteAllBySuppid(suppid);
supprepo.delete(supprepo.findByid(suppid));
}
Upvotes: 2