当前位置: 首页 > 知识库问答 >
问题:

为什么我在Spring Boot应用程序中通过SessionFactory有一个循环依赖项?

景志
2023-03-14

启动Spring Boot应用程序时,我遇到了一个错误。

现在,我想在DAO存储库中使用HibernateDaoSupport,因为Spring Boot不会自动创建SessionFactory。所以,我从EntityManagerFactory创建了SessionFactorybean并尝试在DAO类中自动装配它。

但我有以下错误:

Description:

The dependencies of some of the beans in the application context form a cycle:

   fooDao defined in file [/home/user/test/out/production/classes/by/test/testing_the_java_service_layer/repository/FooDao.class]
┌─────┐
|  sessionFactory defined in class path resource [by/test/testing_the_java_service_layer/configuration/Config.class]
└─────┘

我不明白为什么SessionFactory指的是FooDao类。

以下是代码示例:

食物ao.java

@Repository
public class FooDao extends HibernateDaoSupport
{
    @Autowired
    public void setSessionFactories( SessionFactory sessionFactory )
    {
        setSessionFactory( sessionFactory );

    }

    @Transactional
    public int create( Foo entity )
    {
        return (int) this.getHibernateTemplate().save( entity );
    }
}

Config.java

@ComponentScan( basePackages = { "by.test" } )
@Configuration
public class Config
{
    /*
     *     Spring boot doesn't create SessionFactory bean, so we have to create it manually, using EntityManagerFactory
     */
    @Bean
    public SessionFactory sessionFactory( EntityManagerFactory entityManagerFactory )
    {
        return entityManagerFactory.unwrap( SessionFactory.class );
    }
}

富。Java语言

@Entity
@Table( name = "bibis" )
public class Foo
{
    @Id
    @Column( name = "foo", nullable = false )
    public int foo;

    @Column( name = "bar" )
    public String bar;
}

测试应用程序。Java语言

@SpringBootApplication
public class TestApplication
{

    public static void main( String[] args )
    {
        SpringApplication.run( TestApplication.class, args );
    }
}

application.yaml

spring:
  datasource:
    username: 'bibis'
    password: 'bibis'
    schema: 'bibis'
    host: 'localhost:3306'
    url: 'jdbc:mariadb://localhost:3306/bibis'

以及来自构建的渐变依赖项。格拉德尔

implementation('org.mariadb.jdbc:mariadb-java-client')
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.1.8.RELEASE'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

我尝试使用@Lazy注释、构造函数或字段注入,但没有帮助。

共有3个答案

蔡弘扬
2023-03-14

好吧,你必须弄清楚你是要使用JPA还是Hibernate(JPA的实现),EntityManager对应JPA,SessionFactory对应Hibernate,如果你使用EntityManager就不需要使用SessionFactory,EM会调用底层的hibernate会话。如果您需要一些EntityManager中不可用的特定功能,您可以通过调用来获取会话:

Session session = entityManager.unwrap(Session.class);

重构并尝试

慕逸仙
2023-03-14

在我看来,当您在setter值中使用@Autowired时,它正在创建循环依赖项。作为属性构造函数这样做可能会更好地解决您的问题

@Repository
public class FooDao extends HibernateDaoSupport
{
    @Autowired
    public FooDao(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory
    }

    @Transactional
    public int create( Foo entity )
    {
        return (int) this.getHibernateTemplate().save( entity );
    }
}
孙泉
2023-03-14

我已经将答案从Spring Boot-Handle引用到Hibernate SessionFactory

Config类返回hibernatejpasionFactoryBeanobj而不是SessionFactory对象。

修改后的代码为:

@ComponentScan( basePackages = { "by.test" } )
@Configuration
public class Config
{
    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory entityManagerFactory)
    {
        HibernateJpaSessionFactoryBean hibernateJpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();
        hibernateJpaSessionFactoryBean.setEntityManagerFactory(entityManagerFactory); 
        return hibernateJpaSessionFactoryBean;
    }
}

或者您可以执行以下操作:

@Repository
public class FooDao extends HibernateDaoSupport
{
    @Autowired
    public void setSessionFactories(EntityManagerFactory entityManagerFactory)
    {
        setSessionFactory(entityManagerFactory.unwrap(SessionFactory.class));
    }

    @Transactional
    public int create(Foo entity)
    {
        return (int) this.getHibernateTemplate().save( entity );
    }
}
 类似资料:
  • 应用程序上下文中一些bean的依赖关系形成了一个循环: 我试过用@Lazy,但没用。 当我尝试将构造函数更改为setter时,它会给我错误,例如: 证券配置 UserServiceImpl JWTManager JWTManager是一个自定义类,负责生成新的JWT。它使用来自auth0的java jwt库。通用域名格式。我使用公钥/私钥对令牌进行签名。 AuthController用@RestC

  • 我想写一个计算长除法问题总进位的代码。这是我为carries编写的函数。我相信问题在于,第一个while循环并没有一直运行。如果是,为什么?这是在Python 3.5中实现的。

  • 我目前有一个问题,一个'而'循环不执行。如果输入文本文件有下一行,我将循环条件设置为true。然而,当我执行我的程序时,循环没有运行。我通过添加一个“System.out.println(text)”来确认这一点,正如我所怀疑的,没有产生任何文本。 什么问题导致循环无法执行?

  • 我的grails flyway插件的可传递依赖性有问题<代码>组织。圣杯。插件:grails flyway:0.2.1声明了对org的依赖关系。flywaydb:flyway核心:4.0.1。当我将插件包含到Grails 3.1.6项目中时,Gradle将Flyway降级到3.2.1版本。 我的Gradle构建文件如下所示 目前我不明白为什么Gradle会降低我的传递依赖性。有人能提供这个吗? 我

  • 我想我的程序跳过了while循环,但我真的不确定到底发生了什么。该函数应该通过找到GCD,然后将分子和分母除以该数字来减少分数。 我得到分子和分母的绝对值,以确保如果分数是负数,我会在最后保持它。如果分子为0,则要求我返回(0,1)。问题是关于while循环。。。似乎它被完全跳过了。有什么建议吗?

  • 我正在使用JPA开发Spring Boot v1.4.2.RELEASE应用程序。 我定义了存储库接口和实现 存储库 A存储自定义 ARepositoryImpl公司 和一个服务AServiceImpl 我的应用程序不会以以下消息开始: 我遵循http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositorie