Spring 4 + Hibernate 4: ClassCastException with LocalSessionFactoryBean and SessionFactory - spring

By mean of Spring libraries I have to develope a DAL (Data Access Layer) in the form of a jar library which will be imported into the main application.
I want to use Hibernate to access a MySQL DB and DBCP for the management of the connections pool.
I have written the config file DALConfig.java which contains the configuration of the DAL beans:
package my.dal.config;
import java.util.Properties;
import javax.annotation.Resource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
// Needed by Spring to add this class to the ApplicationContext's configuration
#Configuration
#ComponentScan(basePackages = { "my.dal.config" })
// Property file in which are written the MySQL connection properties
#PropertySource("classpath:dbconnection.properties")
public class DALConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_POOL_INITIAL_SIZE = "pool.initialsize";
private static final String PROPERTY_NAME_POOL_MAX_IDLE = "pool.maxidle";
// Needed to access property file
#Resource
private Environment environment;
// The bean which defines the BasicDataSource (DBCP)
#Bean
public BasicDataSource dataSource() throws Exception
{
Properties props = new Properties();
props.put("driverClassName", environment.getProperty(PROPERTY_NAME_DATABASE_DRIVER));
props.put("url", environment.getProperty(PROPERTY_NAME_DATABASE_URL));
props.put("username", environment.getProperty(PROPERTY_NAME_DATABASE_USERNAME));
props.put("password", environment.getProperty(PROPERTY_NAME_DATABASE_PASSWORD));
props.put("initialSize", environment.getProperty(PROPERTY_NAME_POOL_INITIAL_SIZE));
props.put("maxIdle", environment.getProperty(PROPERTY_NAME_POOL_MAX_IDLE));
BasicDataSource bds = BasicDataSourceFactory.createDataSource(props);
return bds;
}
// Bean used to translate Hibernate's exceptions into Spring's ones
#Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor()
{
PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor();
return b;
}
}
Then I wrote the HibernateConfig.java config file which contains the Hibernate configuration stuff
package my.dal.hibernateconfig;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
#Configuration
#ComponentScan(basePackages = { "my.dal.hibernatesessionfactory" })
#PropertySource("classpath:dbconnection.properties")
public class HibernateConfig {
private static final String PROPERTY_NAME_DAL_CLASSES_PACKAGE = "hibernate.dal.package";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
#Resource
private Environment environment;
#Autowired
DataSource dataSource;
// Bean which defines the FactoryBean for the SessionBean
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setPackagesToScan(PROPERTY_NAME_DAL_CLASSES_PACKAGE);
Properties hibernateProperties = new Properties();
hibernateProperties.put("dialect", PROPERTY_NAME_HIBERNATE_DIALECT);
lsfb.setHibernateProperties(hibernateProperties);
lsfb.setDataSource(dataSource);
return lsfb;
}
#Bean
public HibernateTransactionManager transactionManager()
{
// THE EXCEPTION IS THROWN AT THIS LINE
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory());
return htm;
}
}
Next I wrote the UserDAO.java class which is a DAO for the User class which models the DB's User table.
package my.dal.dao;
import my.models.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Component
#Repository
#Transactional
public class UserDAO
{
private SessionFactory sessionFactory;
#Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory=sessionFactory;
}
public int insert(User user) {
return (Integer) sessionFactory.getCurrentSession().save(user);
}
public User getByUsername(String username) {
return (User) sessionFactory.getCurrentSession().get(User.class, username);
}
public void update(User user) {
sessionFactory.getCurrentSession().merge(user); // .update(user);
}
public void delete(String username) {
User u = getByUsername(username);
sessionFactory.getCurrentSession().delete(u);
}
}
The mapping class User.java (generated using the Eclipse's Hibernate tools) is
package my.models;
public class User implements java.io.Serializable {
private String username;
private String idUserKeystone;
private String firstName;
private String lastName;
private String password;
private String email;
private String emailRef;
private String employer;
private boolean confirmed;
// Getters, setters and full constructor
}
Now I want to test the DAL. The testing class is DALTest.java
package my.dal.tests;
import static org.junit.Assert.assertTrue;
import my.dal.config.DALConfig;
import my.dal.dao.UserDAO;
import my.dal.hibernateconfig.HibernateConfig;
import my.models.User;
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#ContextConfiguration(classes = { DALConfig.class, HibernateConfig.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class DALTest {
#Autowired
UserDAO userDAO;
#Test
public void testGetUser() {
User user = null;
// Let's see if the user "myuser" is into the database
user = userDAO.getByUsername("myuser");
assertTrue(null != user);
}
}
When I run the test it throws the following exceptions
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class my.dal.hibernateconfig.HibernateConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.hibernate4.HibernateTransactionManager my.dal.hibernateconfig.HibernateConfig.transactionManager()] threw exception; nested exception is java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
...
Caused by: java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
at my.dal.hibernateconfig.HibernateConfig.transactionManager(HibernateConfig.java:55)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036.CGLIB$transactionManager$1(<generated>)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036$$FastClassBySpringCGLIB$$119f2c5b.invoke(<generated>)
...
It seems like the problem is the cast at the line
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory())
On the contrary, the Internet is full of example writing that line that way.
What could be the problem?
Thank you in advance

A FactoryBean<Foo> is a bean that creates objects of type Foo. It's not, itself, of type Foo (as the javadoc would show you). To get the Foo it creates, you simply call getObject() on the factory bean:
HibernateTransactionManager htm =
new HibernateTransactionManager(sessionFactory().getObject());

Related

Reactive way of reading YAML with Jackson using Spring boot webflux

The yamlObjectMapper in configuration
#Bean
public ObjectMapper yamlObjectMapper() {
ObjectMapper yamlObjectMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature
.WRITE_DOC_START_MARKER));
yamlObjectMapper.findAndRegisterModules();
return yamlObjectMapper;
}
The Service to parse yaml file
#Service
public class CustomerService {
#Autowired
#Qualifier("yamlObjectMapper")
private ObjectMapper yamlObjectMapper;
public Customer get() {
try {
InputStream inputStream = ResourceUtils.getURL("classpath:/files/test.yaml").openStream();
return yamlObjectMapper.readValue(inputStream, Customer.class);
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
#Data
public static class Customer {
private String name;
private String surname;
private String email;
}
}
I guess IO operations are blocking, how this can be done using reactive way?
I would rather use configuration binding since probably you need to read it once.
package com.vob.webflux.webfilter.controller;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
#Component
#PropertySource(value = "classpath:config.yml", factory= YamlPropertySourceFactory.class)
#Getter
public class YamlFooProperties {
#Value("${test}")
private String test;
}
Factory
package com.vob.webflux.webfilter.controller;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
#Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource)
throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
Source factory from

NoSuchMethodError Table.indexes() hibernate-core-5.2.13.Final.jar when try to start application?

There is application srping+jpa. Webserver is Websphere 8.5.13
So, I launch application by using WebApplicationInitializer where I add configs.
There is problem when added PersisnteceConfig:
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaAuditing
#EnableJpaRepositories(basePackages = {"persistence"})
#PropertySource("classpath:application.properties")
#ComponentScan(basePackages = {"persistence"})
public class PersistenceConfig {
private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_DATABASE_PASSWORD = "db.password";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PACKAGE_WITH_JPA_ENTITIES = "ru.sbrf.risks.services.data.persistence";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
private static final String DO_NOT_AUDIT_LOCKING_FIELD = "org.hibernate.envers.do_not_audit_optimistic_locking_field";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
System.out.println("1");
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
System.out.println("2");
entityManager.setDataSource(dataSource());
System.out.println("3");
entityManager.setPackagesToScan(PACKAGE_WITH_JPA_ENTITIES);
System.out.println("4");
entityManager.setPersistenceProviderClass(HibernatePersistenceProvider.class);
System.out.println("5");
entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
System.out.println("6");
entityManager.setJpaProperties(getHibernateProperties());
System.out.println("7");
return entityManager;
}
#Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
//Set properties hibernate
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getRequiredProperty(PROP_HIBERNATE_DIALECT));
properties.put("hibernate.show_sql", env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));
properties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));
properties.put("org.hibernate.envers.do_not_audit_optimistic_locking_field",
env.getRequiredProperty(DO_NOT_AUDIT_LOCKING_FIELD));
properties.put("verifyServerCertificate", false);
properties.put("useSSL", false);
properties.put("requireSSL", false);
properties.put("useLegacyDatetimeCode", false);
properties.put("useUnicode", "yes");
properties.put("characterEncoding", "UTF-8");
properties.put("serverTimezone", "UTC");
properties.put("useJDBCCompliantTimezoneShift", true);
return properties;
}
}
So,I use hibernate-core-5.2.13.Final libriary and when try to launch application on WebSphere 8.5.13, I have an error message:
Invocation of init method failed; nested exception is
java.lang.NoSuchMethodError:
javax/persistence/Table.indexes()[Ljavax/persistence/Index; (loaded
from
file:/opt/IBM/WebSphere/AppServer/plugins/javax.j2ee.persistence.jar
by org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader#ec08ccb6)
called from class org.hibernate.cfg.annotations.EntityBinder (loaded
from
file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MyApp_war.ear/MyApp.war/WEB-INF/lib/hibernate-core-5.2.13.Final.jar
by
com.ibm.ws.classloader.CompoundClassLoader#7f080f2e[war:MyApp_war/MyApp.war]
You're attempting to use a version of Hibernate that implements a different spec version than the JPA 2.0 included in WebSphere 8.5.5. That can be done, but you'll need to bring your own version of the JPA API as well. To do that, you'll either need to switch your web module's class loader to "Parent Last" or move Hibernate and the JPA API jar(s) to a shared library and configure the library to use an isolated class loader (which effectively sets "Parent Last" just for the jars in the library).

Elasticsearch with cassandra integration

I'm using a jhipster project with cassandra as its repository. Now i also want to integrate elasticsearch with the same project. But getting errors which seem to be that the cassandra is trying to read #Document as its annotation.
Caused by: org.springframework.data.cassandra.mapping.VerifierMappingExceptions: com.shoptell.backoffice.repository.dto.IndexedMergeProductInfoDTO:
Cassandra entities must have the #Table, #Persistent or #PrimaryKeyClass Annotation
at org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntityMetadataVerifier.verify(BasicCassandraPersistentEntityMetadataVerifier.java:45)
at org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntity.verify(BasicCassandraPersistentEntity.java:198)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:297)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:256)
at org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:372)
at org.springframework.data.cassandra.mapping.BasicCassandraMappingContext.initialize(BasicCassandraMappingContext.java:79)
at org.springframework.data.mapping.context.AbstractMappingContext.afterPropertiesSet(AbstractMappingContext.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 144 more
IndexedMergeProductInfoDTO.java
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
#Document(indexName="mergeIndex",type="indexMergeProductInfo")
public class IndexedMergeProductInfoDTO {
#Id
private String id;
private String name;
private String metaCategory;
private String categoryName;
private String subCategoryName;
private String productBrand;
private String productSubBrand;
private String series;
private String model;
CassandraDataAutoConfiguration.java
import com.datastax.driver.core.Cluster;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.CassandraEntityClassScanner;
import org.springframework.data.cassandra.config.CassandraSessionFactoryBean;
import org.springframework.data.cassandra.convert.CassandraConverter;
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
import org.springframework.data.cassandra.core.CassandraAdminOperations;
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext;
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
import javax.inject.Inject;
/**
* {#link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration} for Spring Data's Cassandra support.
* <p/>
* Registers a {#link org.springframework.data.cassandra.config.CassandraSessionFactoryBean} a {#link org.springframework.data.cassandra.core.CassandraAdminOperations} a {#link org.springframework.data.cassandra.mapping.CassandraMappingContext} and a
* {#link org.springframework.data.cassandra.convert.CassandraConverter} beans if no other beans of the same type are configured.
* <p/>
*/
#Configuration
#ConditionalOnClass({Cluster.class, CassandraAdminOperations.class})
#EnableConfigurationProperties(CassandraProperties.class)
#AutoConfigureAfter(CassandraAutoConfiguration.class)
public class CassandraDataAutoConfiguration {
#Inject
BeanFactory beanFactory;
#Inject
private CassandraProperties properties;
#Inject
private Cluster cluster;
#Bean
#ConditionalOnMissingBean
public CassandraSessionFactoryBean session() throws Exception {
CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
session.setCluster(this.cluster);
session.setConverter(cassandraConverter());
session.setKeyspaceName(properties.getKeyspaceName());
return session;
}
#Bean
#ConditionalOnMissingBean
public CassandraAdminOperations cassandraTemplate() throws Exception {
return new CassandraAdminTemplate(session().getObject(), cassandraConverter());
}
#Bean
#ConditionalOnMissingBean
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
BasicCassandraMappingContext bean = new BasicCassandraMappingContext();
bean.setInitialEntitySet(CassandraEntityClassScanner.scan(AutoConfigurationPackages.get(beanFactory)));
bean.setBeanClassLoader(beanFactory.getClass().getClassLoader());
return bean;
}
#Bean
#ConditionalOnMissingBean
public CassandraConverter cassandraConverter() throws Exception {
return new MappingCassandraConverter(cassandraMapping());
}
}
What are the things need to be done to get elasticsearch running?
JHipster can generate a Cassandra + Elasticsearch project -> from my understanding you didn't select that option when generating your project, but if you want to add Elasticsearch, just have a look at how we do it on a new project.
You could also re-generate your project, and add in your .yo-rc.json file:
"searchEngine": "elasticsearch"

How to get Neo4jTemplate in SDN4

I am using Spring Data Neo4j 4(SDN4) from the example project SDN4-northwind(https://github.com/amorgner/sdn4-northwind),when I try to get the Neo4jTemplate bean,I get the error message like this.
Does anyone know how to get the Neo4jTemplate bean from SDN4?
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.neo4j.template.Neo4jTemplate] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at org.neo4j.example.northwind.Run.main(Run.java:34)
Here is the Configuration file
package org.neo4j.example.northwind;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.server.Neo4jServer;
import org.springframework.data.neo4j.server.RemoteServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableNeo4jRepositories("org.neo4j.example.northwind.repository")
#EnableTransactionManagement
public class AppContext extends Neo4jConfiguration {
public static final String NEO4J_HOST = "http://localhost:";
public static final int NEO4J_PORT = 7474;
#Override
public SessionFactory getSessionFactory() {
System.setProperty("username", "neo4j");
System.setProperty("password", System.getProperty("password","osp"));
return new SessionFactory("org.neo4j.example.northwind.model");
}
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer(NEO4J_HOST + NEO4J_PORT);
}
#Bean
#Override
//#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
}
Assdd
#Bean
public Neo4jOperations getNeo4jTemplate() throws Exception {
return new Neo4jTemplate(getSession());
}
to AppContext and then #Autowired Neo4jOperations neo4jTemplate;

Using joda time with JPA/hibernate and spring

I would to persist to db creation date and time. I have some experience with date and time classes but I dont like them.
Recently I've started to use Joda time. I have to say that library is the best to work with date and time.
For now I would like to persist DateTime object from joda.
I've tried already:
#Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime creationDate;
But it unfortunatelly dosnt work. Here is stack trace:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class com.derp.common.init.WebAppConfig: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 41 more
Caused by: org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:510)
at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:42)
at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1472)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1420)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:453)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:438)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 51 more
Caused by: org.hibernate.annotations.common.reflection.ClassLoadingException: Unable to load Class [org.joda.time.contrib.hibernate.PersistentDateTime]
at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:60)
at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:491)
... 61 more
Caused by: java.lang.ClassNotFoundException: org.joda.time.contrib.hibernate.PersistentDateTime
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1324)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1177)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:344)
at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57)
... 62 more
And my fragment of pom.xml:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.5</version>
</dependency>
I hope some one will help me.
----Edited------
WebMvcConfigurerAdapter
package com.derp.common.init;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//import com.derp.common.wicketView.HomePage;
#Configuration
#ComponentScan("com.derp")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
//sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setPackagesToScan(new String[] {
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS)
});
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// Simple strategy: only path extension is taken into account
configurer.favorPathExtension(true).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.TEXT_HTML).
mediaType("html", MediaType.TEXT_HTML).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*");
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*");
registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*");
registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*");
}
}
WebApplicationInitializer class:
package com.derp.common.init;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
public class Initializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
ctx.register(ThymeleafConfig.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setAsyncSupported(true);
servlet.setLoadOnStartup(1);
// Allow to use Put and Delete method for REST architecture
registerHiddenFieldFilter(servletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
}
You can use Jadira for this purpose:
Add this to your pom.xml:
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.extended</artifactId>
<version>3.2.0.GA</version>
</dependency>
And put this in your hibernate properties (hibProperties method in your config class):
properties.put("jadira.usertype.autoRegisterUserTypes", "true");
After you do this you can remove the #Type annotations from your Joda properties and it should work just fine (works for me both for Joda and JSR-310).

Resources