#mongodb #hibernate #hibernate-ogm
#mongodb #спящий режим #переход в спящий режим-ogm
Вопрос:
При попытке настроить Hibernate-ogm для MongoDB в проекте с весенней загрузкой приложение не запускается из-за того, что два метода getSessionFactory()
имеют одинаковую подпись, но возвращают несовместимые типы:
interface org.hibernate.ogm.OgmSessionFactory
interface org.hibernate.engine.spi.SessionFactoryImplementor
Это мои зависимости:
<dependencyManagement>
<dependencies>
<!--This will make sure that you are using matching versions
of the Hibernate OGM modules and their dependencies.-->
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-bom</artifactId>
<version>5.4.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Due to the different inception dates of individual Spring Data modules,
most of them carry different major and minor version numbers.
The easiest way to find compatible ones is to rely on the Spring Data Release
Train BOM that we ship with the compatible versions defined.
-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>${release-train}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--Spring-Boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<!--Mail-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<!--Hibernate-OGM-->
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>narayana-jta</artifactId>
<version>5.9.2.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
</dependencies>
Единственным объектом, задействованным на данный момент, является:
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Indexed;
import javax.persistence.*;
import java.util.List;
@Entity
@Indexed
@Getter
@Setter
public class Email {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@ElementCollection
private List<String> from;
@ElementCollection
private List<String> to;
private String object;
private byte[] eml;
@Column(unique = true)
private byte[] digest;
}
в паре с этим репозиторием:
import my.project.domain.Email;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmailRepository extends JpaRepository<Email, Long> {
}
Вся конфигурация сохранения выполняется с помощью следующего класса конфигурации:
import com.mongodb.MongoClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableJpaRepositories(basePackages = "my.project.repository")
@EnableTransactionManagement
public class DatabaseConfiguration extends AbstractMongoConfiguration {
@Value("${spring.data.mongodb.database}")
private String databaseName;
@Value("${spring.data.mongodb.host}")
private String host;
@Value("${spring.data.mongodb.port}")
private String port;
@Override
public MongoClient mongoClient() {
System.out.println("Port: " port);
MongoClient client = new MongoClient(host, Integer.parseInt(port));
return client;
}
@Override
protected String getDatabaseName() {
return databaseName;
}
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean emf() {
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.transactionType", "resource_local");
properties.put("javax.persistence.provider", "org.hibernate.ogm.jpa.HibernateOgmPersistence");
properties.put("hibernate.ogm.datastore.provider", "mongodb");
properties.put("hibernate.ogm.datastore.host", "localhost");
properties.put("hibernate.ogm.datastore.port", "27017");
properties.put("hibernate.ogm.datastore.database", "myproject");
properties.put("hibernate.ogm.datastore.create_database", "true");
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setPersistenceProviderClass(org.hibernate.ogm.jpa.HibernateOgmPersistence.class); //If your using eclipse or change it to whatever you're using
emf.setPackagesToScan("my.project.domain"); //The packages to search for Entities, line required to avoid looking into the _persistence.xml
emf.setPersistenceUnitName("primary");
emf.setJpaPropertyMap(properties);
//emf.setLoadTimeWeaver(new ReflectiveLoadTimeWeaver()); //required unless you know what your doing
return emf;
}
@Bean(name = "mongoTransactionManager")
public PlatformTransactionManager transactionManager() throws Throwable {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf().getNativeEntityManagerFactory());
return transactionManager;
}
}
Когда я пытаюсь внедрить вышеупомянутый репозиторий, я получаю ошибку, указанную в названии; это весь его журнал:
2019-04-03 10:06:29.101 INFO 9439 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'primary'
2019-04-03 10:06:29.249 WARN 9439 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emailController': Unsatisfied dependency expressed through field 'emailRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: methods with same signature getSessionFactory() but incompatible return types: [interface org.hibernate.ogm.OgmSessionFactory, interface org.hibernate.engine.spi.SessionFactoryImplementor]
2019-04-03 10:06:29.249 INFO 9439 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'primary'
2019-04-03 10:06:29.250 INFO 9439 --- [ main] o.h.o.d.m.impl.MongoDBDatastoreProvider : OGM001202: Closing connection to MongoDB
2019-04-03 10:06:29.252 INFO 9439 --- [ main] org.mongodb.driver.connection : Closed connection [connectionId{localValue:3, serverValue:24}] to localhost:27017 because the pool has been closed.
2019-04-03 10:06:29.257 INFO 9439 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-04-03 10:06:29.263 WARN 9439 --- [ main] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [cluster-ClusterId{value='5ca46983fa224724df0fc9b0', description='null'}-localhost:27017] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForSignalOrTimeout(DefaultServerMonitor.java:229)
com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForNext(DefaultServerMonitor.java:210)
com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:157)
java.lang.Thread.run(Thread.java:748)
2019-04-03 10:06:29.264 WARN 9439 --- [ main] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [CleanCursors-1-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
2019-04-03 10:06:29.283 INFO 9439 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-04-03 10:06:29.301 ERROR 9439 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emailController': Unsatisfied dependency expressed through field 'emailRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: methods with same signature getSessionFactory() but incompatible return types: [interface org.hibernate.ogm.OgmSessionFactory, interface org.hibernate.engine.spi.SessionFactoryImplementor]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at my.project.MyProjectApplication.main(MyProjectApplication.java:19) [classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: methods with same signature getSessionFactory() but incompatible return types: [interface org.hibernate.ogm.OgmSessionFactory, interface org.hibernate.engine.spi.SessionFactoryImplementor]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 19 common frames omitted
Caused by: java.lang.IllegalArgumentException: methods with same signature getSessionFactory() but incompatible return types: [interface org.hibernate.ogm.OgmSessionFactory, interface org.hibernate.engine.spi.SessionFactoryImplementor]
at sun.misc.ProxyGenerator.checkReturnTypes(ProxyGenerator.java:712) ~[na:1.8.0_201]
at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:461) ~[na:1.8.0_201]
at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:339) ~[na:1.8.0_201]
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:639) ~[na:1.8.0_201]
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557) ~[na:1.8.0_201]
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230) ~[na:1.8.0_201]
at java.lang.reflect.WeakCache.get(WeakCache.java:127) ~[na:1.8.0_201]
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419) ~[na:1.8.0_201]
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719) ~[na:1.8.0_201]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createProxy(ExtendedEntityManagerCreator.java:233) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createProxy(ExtendedEntityManagerCreator.java:200) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createApplicationManagedEntityManager(ExtendedEntityManagerCreator.java:104) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:500) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:679) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at com.sun.proxy.$Proxy102.createEntityManager(Unknown Source) ~[na:na]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:302) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at com.sun.proxy.$Proxy105.getDelegate(Unknown Source) ~[na:na]
at org.springframework.data.jpa.provider.PersistenceProvider.fromEntityManager(PersistenceProvider.java:250) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.<init>(JpaRepositoryFactory.java:84) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.createRepositoryFactory(JpaRepositoryFactoryBean.java:106) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.doCreateRepositoryFactory(JpaRepositoryFactoryBean.java:98) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport.createRepositoryFactory(TransactionalRepositoryFactoryBeanSupport.java:80) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:270) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1821) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 29 common frames omitted
Как следует из ошибки, может быть какой-то конфликт зависимостей, но я не смог найти неправильный. Любая мысль об этом?
ОБНОВЛЕНИЕ, добавляющее другую информацию к проблеме; возможно, правильный тип действительно должен быть:
Interface org.hibernate.ogm.engine.spi.OgmSessionFactoryImplementor
Ответ №1:
Я думаю, что Spring Boot и Hibernate OGM включают в ваш проект две разные версии Hibernate ORM, и это вызывает конфликты. Вам нужно проверить, что они оба работают с одной и той же версией, это означает, вероятно, понижение одной из двух.
Кстати, OGM создает свой собственный MongoClient, если у вас возникнут какие-либо проблемы во время подключения, вам может потребоваться обновить конфигурацию или переопределить метод MongoDBDatastoreProvider#createMongoClient
на пользовательском диалекте. Затем вы можете использовать пользовательский диалект вместо стандартного со свойством: hibernate.ogm.datastore.provider
.