0

I am getting the error while using hibernate in spring boot application No qualifying bean of type TransactionManager' available
I am using the following config class:

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@org.springframework.context.annotation.Configuration
@EnableTransactionManagement
public class Config {
    @Bean
    public SessionFactory sessionFactory() {

        Configuration configuration = new Configuration();
        configuration.configure();
        configuration.addAnnotatedClass(Ct.class);
        configuration.addAnnotatedClass(St.class);

        SessionFactory sessionFactory = configuration.buildSessionFactory();
        return sessionFactory;
    }

}  
@RestController
public class RestAPIController {
 @Autowired
    private SessionFactory sessionFactory;

 @PutMapping("/addS")
    @Transactional
    public void addSt(@RequestParam("cc") String cc,@RequestParam("st") String st) {
        CC cc1= new CC();
        CC.setCode(cc);
        State state = new State(cc,st);
        sessionFactory.getCurrentSession().save(state);
    }
}
}  

The main reason I added the @Transactional in the addSt method is due to error: The transaction was still an active when an exception occurred during Database. So I turned to use spring boot for managing transactions. I am not sure what to do here.

--------------------UPDATED CODE--------------------

@Repository
public interface StateRepository extends CrudRepository<State, String> {}


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class StateService {

    @Autowired
    private StateRepository stateRepository;

    public void save(State state) {
        stateRepository.save(state);
    }

    public List<State> findAll() {
        List<State> states = new ArrayList<>();
        stateRepository.findAll().forEach(states::add);
        return states;
    }
}
1
  • Why aren't you just using JPA and let Spring Boot configure it? Also that code belongs in a service not in your controller, imho transactional controllers are a bad design choice. Commented Jun 7, 2022 at 14:08

1 Answer 1

1

For starters use proper layers and write a service and use JPA instead of plain Hibernate. If you want a Session you can always use EntityManager.unwrap to obtain the underlying Session.

@Service
@Transactional
public StateService {

  @PersistenceContext
  private EntityManager em;

  public void save(State state) {
    em.persist(state);
  }

Use this service in your controller instead of the SessionFactory.

@RestController
public class RestAPIController {

    private final StateService stateService;

    RestAPIController(StateService stateService) {
      this.stateService=stateService;
    }

    @PutMapping("/addS")
    public void addSt(@RequestParam("cc") String cc, @RequestParam("st") String st) {
        CC cc1= new CC();
        CC.setCode(cc);
        State state = new State(cc,st);
        stateService.save(state);
    }
}

Now ditch your Config class and restart the application.

NOTE

When using Spring Data JPA it is even easier, define a repository extending CrudRepository and inject that into the service instead of an EntityManager. (I'm assuming that Long is the type of primary key you defined).

public interface StateRepository extends CrudRepository<State, Long> {}
@Service
@Transactional
public StateService {

  private final StateRepository states;

  public StateService(StateRepository states) {
    this.states=states;
  }

  public void save(State state) {
    states.save(state);
  }
}
Sign up to request clarification or add additional context in comments.

18 Comments

@Denium That was really interesting. But for some reason, @PersisenceContext annotation is showing up in red color, even though hibernate-core and spring-boot-starter-data-jpa dependencies are there. Also, what do you suggest for querying the table like select * from state Thanks a lot
You don't need hibernate-core as that is included in spring-boot-starter-data-jpa. The annotation has a type, I fixed the answer, and given the fact you use spring-boot-starter-data-jpa added a StateRepository which makes things even easier, to answer your question in the comment you can just do repository.findAll.
Thanks. @PersistenceContext is working. There was some issue with Intellij. But I am getting the error: A component required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found. Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
During runtime or an IntelliJ inspection? If the latter ignore it.
@Deinum Separately, what is your opinion about my original code, which was tiny compared to the expanded one, with more classes. What do you see are the pros and cons of both approaches.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.