RichColours
RichColours

Reputation: 670

Using ObjectDB with Spring Data JPA "com.objectdb.jpa.EMF is not an interface"

Overflowers

I'm trying to get ObjectDB (2.7.6_01, latest) with Spring Data JPA (2.1.4, seemingly latest).

The docs for Spring Data JPA say that a version 2.1 JPA provider is needed. AFAIKT ObjectDB's JPA provider is 2.0 ... not sure if this is the problem or not.

But my problem is this exception:

Caused by: java.lang.IllegalArgumentException: com.objectdb.jpa.EMF is not an interface

Which is causing:

EntityManagerFactory interface [class com.objectdb.jpa.EMF] seems to conflict with Spring's EntityManagerFactoryInfo mixin - consider resetting the 'entityManagerFactoryInterface' property to plain [javax.persistence.EntityManagerFactory]

I'm happy that the ObjectDB entity manager factory is being picked properly by my code, but Spring's CGLIB wrapper around this class (EMF) is not working out.

Anyone got any ideas?

Gradle dependencies:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compile files('libs/objectdb-jee.jar')
    compileOnly 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Then, either of these two @Beans (one or the other, not both) cause the same EMF exception above:

@Bean
public JpaVendorAdapter jpaVendorAdapter() {

    final ObjectdbJpaVendorAdapter vendorAdapter = new ObjectdbJpaVendorAdapter();

    return vendorAdapter;
}

Or

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    final ObjectdbJpaVendorAdapter vendorAdapter = new ObjectdbJpaVendorAdapter();

    vendorAdapter.setShowSql(true);
    vendorAdapter.setGenerateDdl(false);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);

    factory.setPackagesToScan("com.example.demo.persistence");
    factory.setDataSource(dataSource());
    factory.afterPropertiesSet();

    return factory;
}

I've got a no-op DataSource @Bean to keep some facet of Spring happy, but I don't think it's playing an active role in this problem.

No spring.jpa.* set at all.

Cheers

Upvotes: 1

Views: 395

Answers (1)

Amir Kirsh
Amir Kirsh

Reputation: 13750

The Beans that you have to provide are much more simple:

@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
   return DataSourceBuilder.create().build();
}

@Bean(name="entityManagerFactory")
public EntityManagerFactory getEntityManagerFactoryBean() {
   // this is the important part - here we use a local objectdb file
   // but you can provide connection string to a remote objectdb server
   // in the same way you create objectdb EntityManagerFactory not in Spring
   return Persistence.createEntityManagerFactory("spring-data-jpa-test.odb");
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
   JpaTransactionManager txManager = new JpaTransactionManager();
   txManager.setEntityManagerFactory(emf);
   return txManager;
}

With the above (and the proper dependencies in your pom.xml) there is no need for any additional configuration (i.e. no need for any configuration in application.properties).

A simple working example can be found here.

Upvotes: 1

Related Questions