春季启动:“字段需要找不到类型为'javax.persistence.EntityManagerFactory'的bean。”

时间:2020-01-23 05:57:34

标签: hibernate spring-boot jpa javabeans autowired

我有一个Java项目,该项目将Spring Boot与JPA和Hibernate一起用于数据库。我正在尝试将访问数据库的微服务放在一起。 (我是微服务和Spring Boot的新手。)

以下是主要课程:

@SpringBootApplication
@RestController
@EnableAutoConfiguration
@EnableJpaRepositories
public class CircularsMicroservice {

    @Autowired
    private CircularsService circularsService;



    //microservice called here
    @RequestMapping(value="/circulars-list", method=RequestMethod.POST)
    List<GmCirculars> getAllCircularsForOrganization(@RequestBody  CircularsParams circularsParams)
    {


        List<GmCirculars> circularsList =
                circularsService.fetchAllCircularsForOrganization(circularsParams.getOrganization(), circularsParams.isActiveOnly(), circularsParams.getStartOffset());//invoke the method to get the circulars list
        return circularsList;
    }

    public static void main(String[] args) throws Exception{ 


        SpringApplication springApp= new SpringApplication(CircularsMicroservice.class);

        Map<String, Object> prop= new HashMap<String, Object>();
        prop.put("spring.application.name", "circulars-microservice");
        prop.put("server.port", "8081");
        prop.put("spring.jpa.properties.hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext");

        //db config
        prop.put("spring.datasource.driver-class-name", "oracle.jdbc.driver.OracleDriver");
        prop.put("spring.datasource.url", "--");
        prop.put("spring.datasource.username", "--");
        prop.put("spring.datasource.password", "--");
        prop.put("spring.jpa.show-sql", "false");
        prop.put("spring.jpa.hibernate.ddl-auto", "create-drop");
        prop.put("spring.jpa.properties.hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");

        springApp.setDefaultProperties(prop); //configure programmatically

        springApp.run(args);
        System.out.println("done");


    }    



}

IGmCircularsDAO.class:

@Repository
public interface IGmCircularsDAO {


    /**
     * Save or update.
     *
     * @param obj the obj
     * @return the gm circulars
     */
    GmCirculars saveOrUpdate(GmCirculars obj);




    /**
     * Mark as deleted.
     *
     * @param rowId the row id
     * @return true, if successful
     */
    boolean markAsDeleted(BigDecimal rowId);



    /**
     * Find.
     *
     * @param obj the obj
     * @param activeOnly the active only
     * @param startOffset the start offset
     * @param maxRows the max rows
     * @return the list
     */
    List<GmCirculars> find(GmCirculars obj, boolean activeOnly, int startOffset, int maxRows);



}

GMCircularsDAOImpl.class:

@Repository
@Transactional
@SuppressWarnings("unchecked")
public class GmCircularsDaoImpl extends ParentDAO implements IGmCircularsDAO {

    @Override
    public GmCirculars saveOrUpdate(GmCirculars obj) {

        Session session = null;

        try {
            //session = sessionFactory.openSession(); //commented by Zaid
            session= this.getSession(); //Added by Zaid

            session.beginTransaction();
            session.saveOrUpdate(obj);
            session.flush();
            session.getTransaction().commit();

        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
            session.close();
        }
        return obj;
    }


    @Override
    public List<GmCirculars> find(GmCirculars obj, boolean activeOnly, int startOffset, int maxRows) {
        Session session = null;
        List<GmCirculars> discounts = null;

        try {
            if (null != obj) {

                //session = sessionFactory.openSession(); //commented by Zaid
                session= this.getSession(); //Added by Zaid

                Criteria criteria = session.createCriteria(GmCirculars.class);

                if (null != obj.getId() && !BigDecimal.ZERO.equals(obj.getId())) {
                    criteria.add(Restrictions.eq("id", obj.getId()));
                }

                if (StringUtil.isNotNullOrEmpty(obj.getTitle())) {
                    criteria.add(Restrictions.ilike("title", obj.getTitle(), MatchMode.ANYWHERE));
                }

                if(null != obj.getOrganization()) {
                    criteria.add(Restrictions.eq("organization", obj.getOrganization()));
                }

                //commented by zaid
                /*if (null != obj.getType() && null != obj.getType().getValueId() && !BigDecimal.ZERO.equals(obj.getType().getValueId())) {
                    criteria.add(Restrictions.eq("type.valueId", obj.getType().getValueId()));
                }*/


                if (null != obj.getSerialNo() && !BigDecimal.ZERO.equals(obj.getSerialNo())) {
                    criteria.add(Restrictions.eq("serialNo", obj.getSerialNo()));
                }

                if (null != obj.getYear() && !BigDecimal.ZERO.equals(obj.getYear())) {
                    criteria.add(Restrictions.eq("year", obj.getYear()));
                }


                if (activeOnly) {
                    criteria.add(Restrictions.eq("active", BigDecimal.ONE));
                }
                else {
                    criteria.add(Restrictions.or(Restrictions.ne("active", CommonConstants.DELETED_STATUS), Restrictions.isNull("active"))); //Except for deleted ones -> NVL(active,2)
                }


                //LIMIT startOffset, maxRows;
                criteria.setFirstResult(startOffset);
                criteria.setMaxResults(maxRows);

                criteria.addOrder(Order.desc("id"));
                criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
                discounts = criteria.list();

            }

        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            session.close();
        }
        return discounts;
    }


    @Override
    public boolean markAsDeleted(BigDecimal rowId) {

        Session session = null;
        int updatedRows = 0;
        try {

            //session = sessionFactory.openSession(); //commented by Zaid
            session= this.getSession(); //Added by Zaid

            Query query = session.createQuery("update GmCirculars set active = :statusForDel where id = :rowId");
            query.setParameter("statusForDel", CommonConstants.DELETED_STATUS);
            query.setParameter("rowId", rowId);

            updatedRows = query.executeUpdate();
            session.flush();
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
            session.close();
        }

        return updatedRows > 0;
    }


}

ParentDAO.class

@Transactional
public class ParentDAO {

    //commented by zaid
    //@Autowired
    //protected SessionFactory sessionFactory;

        //added by Zaid //spring boot way
        //@Autowired

        @PersistenceContext
        protected EntityManager entityManager;

        protected Session getSession() {
            return entityManager.unwrap(Session.class);

        }



}

CircularsService.class

@org.springframework.stereotype.Service
public class CircularsService {

    @Autowired
    private IGmCircularsDAO gmCircularDao;



    @Value("${circulars.maxRows}")
    private int circularsMaxRows;


    /**
     * Save or update.
     *
     * @param obj the obj
     * @return the gm circulars
     */
    public GmCirculars saveOrUpdate(GmCirculars obj) {
        return gmCircularDao.saveOrUpdate(obj);
    }


    /**
     * Find.
     *
     * @param obj the obj
     * @param activeOnly the active only
     * @param startOffset the start offset
     * @return the list
     */
    public List<GmCirculars> find(GmCirculars obj, boolean activeOnly, int startOffset) {
        return gmCircularDao.find(obj, activeOnly, startOffset, circularsMaxRows);
    }


    /**
     * Fetch all circulars for organization.
     *
     * @param userOrg the user org
     * @param activeOnly the active only
     * @param startOffset the start offset
     * @return the list
     */
    public List<GmCirculars> fetchAllCircularsForOrganization(Organization userOrg, boolean activeOnly, int startOffset) {

        GmCirculars criteria = new GmCirculars();
        criteria.setOrganization(userOrg);
        return gmCircularDao.find(criteria, activeOnly, startOffset, circularsMaxRows);
    }


    /**
     * Find by id.
     *
     * @param id the id
     * @return the gm circulars
     */
    public GmCirculars findById(BigDecimal id) {
        GmCirculars result = null;

        List<GmCirculars> discs = gmCircularDao.find(new GmCirculars(id), false, 0, circularsMaxRows);

        if (null != discs && !discs.isEmpty()) {
            result = discs.get(0);
        }
        return result;
    }


    /**
     * Mark as deleted.
     *
     * @param entryId the entry id
     * @return true, if successful
     */
    public boolean markAsDeleted(BigDecimal entryId) {
        return gmCircularDao.markAsDeleted(entryId);
    }
}

运行此代码时,我遇到了以下错误,但现在已经有一段时间了。

ERROR LoggingFailureAnalysisReporter 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field gmCircularDao in service.CircularsService required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.

如何解决?谢谢。

2 个答案:

答案 0 :(得分:0)

春天是对的

您正在使用弹簧数据(@Repository public interface IGmCircularsDAO extends JpaRepository<GmCirculars, BigDecimal>

spring数据的重点是在运行时基于此接口生成一个实现。此实现已注册为实现IgmCircularDao接口的Bean)

现在,在您创建一个bean的正下方:

@Repository
@Transactional
@SuppressWarnings("unchecked")
public class GmCircularsDaoImpl extends ParentDAO implements IGmCircularsDAO {
...

因此,spring再次扫描并找到该存储库,并尝试将其注册为bean。它还实现了相同的接口,因此spring有两个bean,它们相互竞争以获取向服务注入的权利:

public class CircularsService {

    @Autowired
    private IGmCircularsDAO gmCircularDao; // <-- what should spring chose? an autogenerated spring data proxy or your own implementation???
...

出现异常...

您应该了解您是否要维护两个实现相同接口的存储库,如果要维护,那么当您要将其中任何一个注入服务时如何区分它们(就像CircularService一样)

您可以使用限定词和不同的界面-有很多解决方案,但同样,您首先应该了解最适合自己的用法

答案 1 :(得分:0)

问题出在Spring Boot 2.x发行版使用的休眠版本。在休眠版本以下添加解决了该问题,

<properties>
    <hibernate.version>5.2.14.Final</hibernate.version>
</properties>