I have developed a simple application using In Memory HSQLDB and it runs in Websphere Liberty Profile 8.5 over Windows. Now I have published such application in Websphere over z/OS390 Mainframe (Unix) and I am getting the error below.
As far as understand, it should not be affected by the Operation System since it is the same jar (hsqldb-2.3.2.jar), same JDK version (7) and exact same myapp.ear file.
So, my straight question is: what could be the reason for "NoSuchMethodError: javax/persistence/Table.indexes" during entityManagerFactory creation?
What make my life harder is that the exact same ear deployed in my local Websphere doesn't pop up such error. An indirect question could be, is any trick to make in memory HSQLDB run in Unix? Am I reading wrongly the logs and such error is in fact caused by some wrong Spring config? I don't think so because exact same ear runs in another Websphere as said.
I have been struggling for 4 days to find a possible reason but I couldn't. Any suggestion will be highly appreciatted.
Error Logs:
WebSphere non-WLM Dispatch Thread t=009bb7a0¨ ContextLoader - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory'
defined in myapp.config.root.TestConfiguration: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax/persistence/Table.indexes()ÝLjavax/persistence/Index;
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java
TestConfiguration.java
@Configuration
@EnableTransactionManagement
public class TestConfiguration {
@Bean(initMethod = "init")
public TestDataInitializer initTestData() {
return new TestDataInitializer();
}
@Bean(name = "datasource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(org.hsqldb.jdbcDriver.class.getName());
dataSource.setUrl("jdbc:hsqldb:mem:mydb");
dataSource.setUsername("sa");
dataSource.setPassword("jdbc:hsqldb:mem:mydb");
System.out.println("Untill here was printed without error");
return dataSource;
}
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DriverManagerDataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan(new String[]{"myapp.model"});
entityManagerFactoryBean.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Map<String, Object> jpaProperties = new HashMap<String, Object>();
jpaProperties.put("hibernate.hbm2ddl.auto", "create");
jpaProperties.put("hibernate.show_sql", "true");
jpaProperties.put("hibernate.format_sql", "true");
jpaProperties.put("hibernate.use_sql_comments", "true");
entityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
System.out.println("Untill here was printed without error also");
return entityManagerFactoryBean;
}
}
TestDataInitializer
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManagerFactory;
@Component
public class TestDataInitializer {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
AnotherModelRepository anotherModelRepository;
public void init() throws Exception {
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
… few session.persit(mymodel)…
POM:
<properties>
<java-version>1.7</java-version>
<org.springframework-version>4.1.3.RELEASE</org.springframework-version>
<spring-security-version>3.2.5.RELEASE</spring-security-version>
<hibernate.version>4.3.7.Final</hibernate.version>
<org.slf4j-version>1.6.1</org.slf4j-version>
<jackson-version>2.4.4</jackson-version>
<postgres.driver.version>9.3-1100-jdbc41</postgres.driver.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.driver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Spring security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>com.allanditzel</groupId>
<artifactId>spring-security-csrf-token-filter</artifactId>
<version>1.1</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- Jackson JSON Processor -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- servlet container provided dependencies -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.30</version>
<scope>provided</scope>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>0.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
<build>
<finalName>my-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
**** Added in August 28th 2016 2:45am Brazil, São Paulo timezone Thanks to the excellent answers provided, I finaly have my application running in both Windows Websphere 8.5 Liberty Profile as in Mainframe z/OS390 Websphere ND 8.5. I added here my solution for future readers. The basic trick was (1) downgrade Hibernate in order to use JPA2 and use EntityManager.getDelegate()
@Component
public class TestDataInitializer {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
AnotherModelRepository anotherModelRepository;
// I TOOK @PersistenceContext OUT
/* @PersistenceContext
private EntityManager em;*/
public void init() throws Exception {
// I REPLACED entityManagerFactory.unwrap AND sessionFactory.openSession OUT
//SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
//Session session = sessionFactory.openSession();
// BY createEntityManager AND getDelegate
EntityManager em = entityManagerFactory.createEntityManager();
Session session = (Session) em.getDelegate();
Transaction transaction = session.beginTransaction();
…
@Repository
public class MyModelRepository {
/* @PersistenceContext
private EntityManager em;*/
@Autowired
private EntityManagerFactory entityManagerFactory;
public MyModel findMyModelById(Long MyModel) {
EntityManager em = entityManagerFactory.createEntityManager();
List<MyModel> MyModels = em.createNamedQuery(MyModel.FIND_BY_ID, MyModel.class).setParameter("MyModelId", MyModel).getResultList();
return MyModels.size() == 1 ? MyModels.get(0) : null;
}
public List<MyModel> findOutByIn(Integer certainId){
//SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
EntityManager em = entityManagerFactory.createEntityManager();
Session session = (Session) em.getDelegate();
String query = "select c from … c "
+ " inner join … o "
+ " where …;
//Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
List<MyModel> l = session.createQuery(query).list();
return l;
}
You are getting below error.
This error is indicating that required method is not available in the particular class. The "indexes()" method is available at "javax.persistence.Table" class of JPA 2.1 jar (hibernate-jpa-2.1-api). Some how in your deployment it is picking up JPA 2.0 jar (hibernate-jpa-2.0-api) which doesn't have this method in Table class. In your pom.xml you are using "hibernate-entitymanager 4.3.7.Final", which provides JPA 2.1 jar file. Please look for the JPA 2.0 jars file in your server where you are getting this error.