Я искал в Google автономные приложения Hibernate / Spring, но не нашел ни одного полезного примера. Кажется, что большинство людей используют его только для веб-приложений.
Вот что у меня есть:
Основной класс:
@Component
public class App {
@Inject
SessionFactory sessionFactory;
Fruit apple;
Serializable appleId;
@Transactional
void testCreate() {
apple = new Fruit();
apple.setName("Apple");
apple.setPrice(10);
HibernateTemplate template = new HibernateTemplate(sessionFactory);
appleId = template.save(apple);
System.out.println("New Apple: " + apple);
}
@Transactional
void testReload() {
HibernateTemplate template = new HibernateTemplate(sessionFactory);
final Fruit reload = template.load(Fruit.class, appleId);
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
System.out.println("Update");
session.update(reload);
System.out.println("Reload: " + reload);
}
public void run()
throws Exception {
testCreate();
testReload();
}
public static void main(String[] args)
throws Exception {
new ClassPathXmlApplicationContext("context.xml").getBean(App.class).run();
}
}
В этом примере после успешной вставки нового Apple
в базу данных функция reload () подпоследовательности выдает:
Выход:
Hibernate:
/* insert my.hibernate.Fruit
*/ insert
into
Food
(id, rank, version, name, price, DTYPE)
values
(null, ?, ?, ?, ?, 'Fruit')
DEBUG [main] (HibernateAccessor.java:389) - Eagerly flushing Hibernate session
New Apple: 1, Apple
DEBUG [main] (HibernateAccessor.java:389) - Eagerly flushing Hibernate session
Update
Hibernate:
/* load my.hibernate.Fruit */ select
fruit0_.id as id0_0_,
fruit0_.rank as rank0_0_,
fruit0_.version as version0_0_,
fruit0_.name as name0_0_,
fruit0_.price as price0_0_
from
Food fruit0_
where
fruit0_.id=?
and fruit0_.DTYPE='Fruit'
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [my.hibernate.Fruit#1]
at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:419)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:154)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:143)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:174)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at my.hibernate.Fruit_$$_javassist_0.toString(Fruit_$$_javassist_0.java)
at java.lang.String.valueOf(String.java:2902)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at my.hibernate.App.testReload(App.java:86)
Кажется, testCreate()
ничего не совершал. Есть идеи?
EDIT
context.xml
:
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<context:component-scan base-package="my" />
</beans>
И сессионный заводской конфиг:
@Component
public class TestH2DataSource
extends BasicDataSource {
public TestH2DataSource() {
setDriverClassName("org.h2.Driver");
setUrl("jdbc:h2:target/testdb;DB_CLOSE_ON_EXIT=FALSE");
setUsername("sa");
setPassword("");
setDefaultAutoCommit(false);
}
}
@Component
public class TestSessionFactory
extends AnnotationSessionFactoryBean {
@Inject
DataSource dataSource;
public TestSessionFactory() {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "true");
properties.setProperty("hibernate.use_sql_comments", "true");
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
this.setHibernateProperties(properties);
this.setAnnotatedClasses(new Class<?>[] { Fruit.class });
}
@Override
public void afterPropertiesSet()
throws Exception {
this.setDataSource(dataSource);
super.afterPropertiesSet();
}
}
@Configuration
public class OtherContextConfiguration {
@Inject
SessionFactory sessionFactory;
@Bean
public HibernateInterceptor hibernateInterceptor() {
HibernateInterceptor hibernateInterceptor = new HibernateInterceptor();
hibernateInterceptor.setSessionFactory(sessionFactory);
return hibernateInterceptor;
}
@Bean
public HibernateTransactionManager hibernateTransactionManager() {
HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager();
hibernateTransactionManager.setSessionFactory(sessionFactory);
return hibernateTransactionManager;
}
}