无法延迟初始化角色集合:myapp.myapp.models.Contact.messages,无法初始化代理 - 无会话

C. *_*ith 3 hibernate jpa spring-data-jpa spring-boot

我遇到 org.hibernate.LazyInitializationException:无法延迟初始化角色集合:myapp.myapp.models.Contact.messages,无法初始化代理 - 无会话。我研究过这些类似的问题Hibernate: LazyInitializationException: failed to lazily初始化角色集合。无法初始化代理 - 没有会话以及如何解决 \xe2\x80\x9cfailed to lazily初始化角色\xe2\x80\x9d Hibernate 异常的集合,但它们都没有帮助我的情况。我将 spring 自动配置我的数据源到了没有这个问题的地方,但我添加了另一个数据源连接,然后为每个数据源创建了一个配置文件,现在一切正常,就像以前一样,但我不断收到此消息抛出错误。我不知道该怎么办。任何帮助表示赞赏。

\n\n

在添加其他数据库之前,我的属性文件中的数据库信息看起来像这样

\n\n
##############DBs##################\nspring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect\nspring.jpa.hibernate.ddl-auto=update\nspring.jpa.database=default\n\n#Myapp DB\nspring.datasource.driverClassName=com.mysql.jdbc.Driver\nspring.datasource.url=jdbc:mysql://localhost:3306/myapp?        verifyServerCertificate=false&useSSL=false&requireSSL=false\nspring.datasource.username=myusername\nspring.datasource.password=mypassword\n
Run Code Online (Sandbox Code Playgroud)\n\n

一切顺利。

\n\n

现在一切都是这样设置的。

\n\n

属性文件

\n\n
##############DBs##################\nspring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect\nspring.jpa.hibernate.ddl-auto=update\nspring.jpa.database=default\n\n#Myapp DB\nspring.datasource.driverClassName=com.mysql.jdbc.Driver\nspring.datasource.url=jdbc:mysql://localhost:3306/myapp?        verifyServerCertificate=false&useSSL=false&requireSSL=false\nspring.datasource.username=myusername\nspring.datasource.password=mypassword\n\n#Other DB\nspring.seconddatasource.driverClassName = com.mysql.jdbc.Driver\nspring.seconddatasource.url = jdbc:mysql://localhost:3306/other\nspring.seconddatasource.username=myusername\nspring.seconddatasource.password=mypassword\n###################################\n
Run Code Online (Sandbox Code Playgroud)\n\n

联系单位:

\n\n
@Entity\n@Table(name = "contact")\npublic class Contact {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private long id;\n\n    @OneToMany(fetch = FetchType.LAZY, mappedBy = "contact")\n    private List<Messages> messages;\n\n    public long getId() {\n        return this.id;\n    }\n\n    public void setId(long id) {\n        this.id = id;\n    }\n\n    public List<Messages> getMessages() {\n        return this.messages == null ? null : new ArrayList<>(this.messages);\n    }\n\n    public void setMessages(List<Messages> messages) {\n        this.messages = messages;\n    }\n\n    public void addMessage(Messages message) {\n        this.messages.add(message); // this is where the error is being thrown\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

消息实体:

\n\n
@Entity\n@Table(name = "message")\npublic class Contact {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private long id;\n\n    @ManyToOne\n    @JoinColumn(name = "contactId", nullable = false)\n    private Contact contact;\n\n    public long getId() {\n        return this.id;\n    }\n\n    public void setId(long id) {\n        this.id = id;\n    }\n\n    public Contact getContact() {\n         return this.contact;\n    }\n\n    public void setContact(Contact contact) {\n         this.contact = contact;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

新的MyAppConfigClass(一旦将其与其他一起放入,错误就开始发生):

\n\n
@ComponentScan\n@Configuration\n@EnableJpaRepositories(\n    basePackages = { "myapp.myapp" },\n    entityManagerFactoryRef = "myappEntityManagerFactory",\n    transactionManagerRef = "myappTransactionManager")\n@EnableTransactionManagement\npublic class MyAppDBConfiguration {\n\n    @Autowired private ApplicationContext applicationContext;\n\n    @Bean(name = "myappExceptionTranslator")\n    public HibernateExceptionTranslator personnelHibernateExceptionTranslator() {\n        return new HibernateExceptionTranslator();\n    }\n\n    @Bean(name = "myappTransactionManager")\n    public PlatformTransactionManager personnelTransactionManager() {\n        return new JpaTransactionManager(personnelEntityManagerFactory().getObject());\n    }\n\n    @Bean(name = "myappEntityManagerFactory")\n    public LocalContainerEntityManagerFactoryBean personnelEntityManagerFactory() {\n\n        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();\n        vendorAdapter.setGenerateDdl(true);\n\n        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();\n        factory.setJpaVendorAdapter(vendorAdapter);\n        factory.setPackagesToScan("myapp.myapp");\n        factory.setDataSource(myappDataSource());\n        factory.afterPropertiesSet();\n\n        return factory;\n\n    }\n\n    @Primary\n    @Bean(name = "myappDataConfig")\n    @ConfigurationProperties("spring.datasource")\n    public DataSourceProperties myappProperties() {\n        return new DataSourceProperties();\n    }\n\n    @Bean(name = "myappData", destroyMethod = "")\n    public DataSource myappDataSource() {\n        DataSourceProperties properties = myappProperties();\n        if (null != properties.getJndiName()) {\n            JndiDataSourceLookup lookup = new    JndiDataSourceLookup();\n            DataSource source = lookup.getDataSource(properties.getJndiName());\n            excludeMBeanIfNecessary(source, "myappData");\n            return source;\n        } else {\n            return properties.initializeDataSourceBuilder().build();\n        }\n    }\n\n    private void excludeMBeanIfNecessary(Object candidate, String beanName) {\n        try {\n            MBeanExporter mbeanExporter = this.applicationContext.getBean(MBeanExporter.class);\n            if (JmxUtils.isMBean(candidate.getClass())) {\n                mbeanExporter.addExcludedBean(beanName);\n            }\n        } catch (NoSuchBeanDefinitionException ex) {\n            // No exporter. Exclusion is unnecessary\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是OtherConfigClass(几乎完全相同):

\n\n
@ComponentScan\n@Configuration\n@EnableJpaRepositories(\n    basePackages = { "myapp.other" },\n    entityManagerFactoryRef = "otherEntityManagerFactory",\n    transactionManagerRef = "otherTransactionManager")\n@EnableTransactionManagement\npublic class OtherDBConfiguration {\n\n    @Autowired private ApplicationContext applicationContext;\n\n    @Bean(name = "otherExceptionTranslator")\n    public HibernateExceptionTranslator personnelHibernateExceptionTranslator() {\n        return new HibernateExceptionTranslator();\n    }\n\n    @Bean(name = "otherTransactionManager")\n    public PlatformTransactionManager personnelTransactionManager() {\n        return new JpaTransactionManager(personnelEntityManagerFactory().getObject());\n    }\n\n    @Bean(name = "otherEntityManagerFactory")\n    public LocalContainerEntityManagerFactoryBean personnelEntityManagerFactory() {\n\n        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();\n        vendorAdapter.setGenerateDdl(true);\n\n        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();\n        factory.setJpaVendorAdapter(vendorAdapter);\n        factory.setPackagesToScan("myapp.other");\n        factory.setDataSource(otherDataSource());\n        factory.afterPropertiesSet();\n\n        return factory;\n\n    }\n\n    @Bean(name = "otherDataConfig")\n    @ConfigurationProperties("spring.seconddatasource")\n    public DataSourceProperties otherProperties() {\n        return new DataSourceProperties();\n    }\n\n    @Bean(name = "otherData", destroyMethod = "")\n    public DataSource textappotherDataSource() {\n        DataSourceProperties properties = myappProperties();\n        if (null != properties.getJndiName()) {\n            JndiDataSourceLookup lookup = new    JndiDataSourceLookup();\n            DataSource source = lookup.getDataSource(properties.getJndiName());\n            excludeMBeanIfNecessary(source, "otherData");\n            return source;\n        } else {\n            return properties.initializeDataSourceBuilder().build();\n        }\n    }\n\n    private void excludeMBeanIfNecessary(Object candidate, String beanName) {\n        try {\n            MBeanExporter mbeanExporter = this.applicationContext.getBean(MBeanExporter.class);\n            if (JmxUtils.isMBean(candidate.getClass())) {\n                mbeanExporter.addExcludedBean(beanName);\n            }\n        } catch (NoSuchBeanDefinitionException ex) {\n            // No exporter. Exclusion is unnecessary\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是应用程序类:

\n\n
@EnableAutoConfiguration\n@SpringBootApplication\npublic class MyApplication {\n\n    public static void main(String[] args) {\n            SpringApplication.run(MyApplication.class, args);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我假设我缺少一些新的配置文件,这些文件是在 AutoConfig 之外完成的。这是我所做的唯一更改,它开始抛出错误。正如我上面所说,数据已正确保存到数据库中,但仍会引发该错误。

\n\n

我不知道为什么会出现这种情况,解释会非常有帮助。

\n\n

更新:

\n\n

联系存储库:

\n\n
@Repository\npublic interface ContactRepository extends JpaRepository<Contact, Long> {\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

消息存储库:

\n\n
@Repository\npublic interface MessagesRepository extends JpaRepository<Messages, Long> {\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

服务等级:

\n\n
@Service\npublic void serviceClass(long id) {\n    Contact contact = contactRepository.findOne(id);\n    Messages msg = new Messages();\n    msg.setContact(contact);\n\n    // do some work here\n\n    Messages savedMessage = messagesRepository.save(msg);\n    contact.addMessage(savedMessage);\n    contactRepository.save(contact);\n
Run Code Online (Sandbox Code Playgroud)\n

Dr.*_*ICI 7

在 application.properties 文件中设置enable_lazy_load_no_trans=true在我的情况下解决了,无需将获取类型从惰性更改为急切。

  • 小更正:应该是 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true (4认同)