I continue getting the following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'StorageItemRepository'
My beans.xml is set to find all - located in META-INF/beans.xml of every module resource file. My Repository class does have #Repository on it and my web.xml is definitely configured to find the bean.
It's worth noting - this working when deployed - just not for the below unit test.
My unit test:
/**
* Test for {#link StorageItemRepository}
*/
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"classpath:JDBCConfig.xml"})
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = {"com.app.storage.persistence.repository"})
public class StorageItemRepositoryTest {
/** {#link StorageItemRepository} */
#Autowired
private StorageItemRepository storageItemRepository;
/**
* Finds all storage items in db.
*/
#Test
public void checkFindAllItems(){
final StorageItemPersistenceModel storageItemPersistenceModel = new StorageItemPersistenceModel();
storageItemPersistenceModel.setId(1L);
storageItemPersistenceModel.setDateStored(new DateTime());
storageItemPersistenceModel.setName("Name");
storageItemRepository.save(storageItemPersistenceModel);
}
}
JDBCConfig file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/storage_app_schema" />
<property name="username" value="root" />
<property name="password" value="dollar123" />
</bean>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.app.storage.persistence.model" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="persistenceUnitName" value="app_test"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf"/>
</bean>
</beans>
The persistence.xml is definitely fine and working so not the cause.
How are you running the unit test?
Since it is working when deployed, and not in the unit test, I am inclined to suspect that the unit test execution has a missing classpath, such as JDBCConfig.xml doesn't exist in the execution classpath
Related
Im trying to save the data into PostgreSQL database, I configure my dataSource bean:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/testdb"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
<!-- <property name="initialSize" value="5"/>-->
<!-- <property name="maxActive" value="10"/>-->
</bean>
then insert them into sessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.nazik.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.PostgreSQL10Dialect</prop>
</props>
</property>
</bean>
and configure transactionManager
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
but when I start transaction using code:
#Override
public void createPerson(final Person person) {
transactionTemplate.execute(new TransactionCallback<Void>() {
public Void doInTransaction(TransactionStatus transactionStatus){
try{
createPerson(person);
}catch (RuntimeException e){
transactionStatus.setRollbackOnly();
throw e;
}
return null;
}
});
}
i have got an error:
Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'transactionManager' is expected to be of type 'org.hibernate.SessionFactory' but was actually of type 'org.springframework.orm.hibernate5.HibernateTransactionManager'
at org.springframework.beans.factory.support.AbstractBeanFactory.adaptBeanInstance(AbstractBeanFactory.java:417)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:398)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1160)
please explain me what am I doing wrong
I'm not completely sure since I have no way to test but at least the exception says that the configuration of 'transaction manager' receives the wrong type of parameter.
you can test this way.
<bean id = "transactionManager"
class = "org.hibernate.SessionFactory">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
You can try to see if it is that, I leave you as an answer since I can not comment yet.
Pdt: as a personal recommendation I suggest you use JPA since it has a simpler handling of transactions
I could test this on similar setup and configuration except I am using HibernateTemplate. Since you are using Hibernate - you should be generally using HibernateTemplate or even better JPA APIs ( which can be used as Hibernate underlying JPA implementation)
You can also use #Transactional annotation rather than programatically defining your boundaries and exception handling.
My sample configuration looks like this
<?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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<tx:annotation-driven />
<context:component-scan base-package="springmvc"></context:component-scan>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
name="viewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
name="ds">
<property name="driverClassName"
value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/springjdbc" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
name="sessionFactory">
<property name="dataSource" ref="ds" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>springmvc.model.User</value>
</list>
</property>
</bean>
<bean class="org.springframework.orm.hibernate5.HibernateTemplate"
name="hibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean
class="org.springframework.orm.hibernate5.HibernateTransactionManager"
name="transactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
And my data saving code looks like this
#Autowired
private HibernateTemplate hibernateTemplate;
#Transactional
public int saveUser(User user) {
int id = (Integer)this.hibernateTemplate.save(user);
return id;
}
And I can save data in database ( MySQL in my case but that is irrelevant here)
I am working on project with Spring mvc and i want to use jpa features as well.
I have an 3 entity classes, their corresponding repository interfaces. I have their autowired objects in common service class. However I am facing issues while creating bean for this service class object which is used in controller.
The 3 model class are User, Appointment and Notification.
The repository interface extends CRUDRepository interface.
Service class :
#Service
public class EHealthService
{
#Autowired
UserRepository uRepo;
#Autowired
AppointmentRepository aRepo;
#Autowired
NotificationRepository nRepo;
public void registerUser(User u)
{
uRepo.save(u);
}
public boolean login(User u)
{
if(uRepo.findByemail(u.getEmail())!=null)
return true;
else
return false;
}
public List<User> getDoctorList()
{
return uRepo.findByisdoctor(true);
}
// some more functions
}
Controller class:
#Controller
public class EHealthController
{
#Autowired
EHealthService eservice;
//Some code
}
ehealth-dispacter-servlet.xml file:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:component-scan base-package="com.cl3.controller" />
<context:component-scan base-package="com.cl3.model" />
<context:component-scan base-package="com.cl3.service" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="packagesToScan" value="com.cl3.model"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<jpa:repositories base-package="com.cl3.model"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/cl3" />
<property name="username" value="ucan" />
<property name="password" value="ucan" />
</bean>
<bean id="eservice" class="com.cl3.service.EHealthService">
<property name="uRepo" ref="uRepo"></property>
<property name="nRepo" ref="nRepo"></property>
<property name="aRepo" ref="aRepo"></property>
</bean>
<bean id="uRepo" class="com.cl3.model.UserRepository">
</bean>
<bean id="nRepo" class="com.cl3.model.NotificationRepository">
</bean>
<bean id="aRepo" class="com.cl3.model.AppointmentRepository">
</bean>
It says the class is an interface.
What will be the bean for eservice object and to enable jpa in dispacter servel xml file?
Thank you.
If you are using spring xml based configuration then add below bean's to configuration file :
<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- This makes /META-INF/persistence.xml is no longer necessary -->
<property name="packagesToScan" value="com.howtodoinjava.demo.model" />
<!-- JpaVendorAdapter implementation for Hibernate EntityManager.
Exposes Hibernate's persistence provider and EntityManager extension interface -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
Register component scanning by adding this binding annotation in xml file :
<context:component-scan base-package="com.mycompany.projectname.demo" />
If your project is spring mvc the add below binding annotation to xl file
<!-- This allow for dispatching requests to Controllers -->
<mvc:annotation-driven />
For declarative transaction management add below piece in xml file.
<tx:annotation-driven />
Basically you no need to add service bean in xml configuration file if you are enabled component scanning feature in spring.
Add required dependencies to integrate jpa with spring.
Refer this link will help you more :
https://howtodoinjava.com/jpa/spring-hibernate-jpa-configuration-example/
I previously had this config for Hibernate using RESOURCE-LOCAL transaction type:
persistence.xml:
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
applicationContext (dataaccess bit):
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"></bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceUnitName" value="myPU"/>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<!-- Are there any other properties required? -->
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/CNTXESDB" />
<property name="lookupOnStartup" value="true" />
<property name="cache" value="true" />
<property name="proxyInterface" value="javax.sql.DataSource" />
</bean>
But this kind of transaction seems not to work with Glassfish, so I had to switch to JTA transactions.
The problem is -- to get Spring to manage transaction creation (through #Transactional) I need to define a TransactionManager bean but JtaTransactionManager included in spring-tx does not accept an entityManagerFactory bean, so it does not know where the entityManager is in order to open/close/flush Hibernate session.
So how can I configure Spring with Hibernate to use JTA transactions?
EDIT:
turns out you can use RESOURCE_LOCAL transactions with Glassfish, but somehow you cannot have a persistence.xml file. I renamed this file to my_persistence.xml and configured LocalContainerEntityManagerFactoryBean like this:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceUnitName" value="myPU"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/my_persistence.xml" />
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>
I had a similar problem and finally I solved as you can see in this little demo:
https://github.com/miguelangelprogramacion/spring4_jpa_hibernate
With [1] as a reference, I prefer to use Spring's Transaction Support before JTA.
Also, I've used an annotation based approach.
[1] http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/
This is the first time I can't find a solution to my problem on stackoverflow:
I'm trying to create an executable-jar standalone application with annotation-based autowiring, but I can't get the runnable jar file (exported from Eclipse as runnable JAR file) to do it's job. It does run as Java application from Eclipse directly, just not as standalone app via console > java -jar test.jar.
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'handler': Injection of autowired dependen
cies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.serv
ice.UserService com.example.controller.TestHandler.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionEx
ception: No qualifying bean of type [com.example.service.UserService] found for dependency: expected at least 1 bean which qualifies as auto
wire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBe
anPostProcessor.java:288)
I tried to avoid such problems by following the pattern 'Initialize autowiring manually' described on this blog: http://sahits.ch/blog/?p=2326 to no avail.
Note that I'm also using Hibernate JPA without a persistence.xml (therefore <tx:annotation-driven/> ) - and don't get obstructed by the two databases I use, it works fine when running from within Eclipse.
Main.java:
public class Main {
#Autowired
private TestRunner testRunner;
public Main() {
final ApplicationContext context = new ClassPathXmlApplicationContext("app-context.xml");
AutowireCapableBeanFactory acbFactory = context.getAutowireCapableBeanFactory();
acbFactory.autowireBean(this);
}
public static void main(String[] args) throws Exception {
Main main = new Main();
main.testRunner.run();
}
}
TestRunner.java:
#Component
public class TestRunner {
#Autowired
Handler handler;
public void run() {
handler.doTest();
}
}
TestHandler.java (groupId and groupName will be set in a later stage):
#Controller
public class TestHandler implements Handler {
private static Log syslog = LogFactory.getLog(TestHandler.class);
#Autowired
private UserService userService;
#Autowired
private GroupService groupService;
private Long groupId;
private String groupName;
public void doTest() {
if (groupId != null) {
List<User> users = userService.loadUsersByGroupId(groupId);
syslog.debug("Amount of users found: " + users.size());
} else {
syslog.debug("groupId is null");
}
if (groupName != null) {
List<Group> groups = groupService.loadGroupsByName(groupName);
syslog.debug("Amount of groups found: " + groups.size());
} else {
syslog.debug("groupName is null");
}
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
}
UserServiceImpl.java:
#Service
public class UserServiceImpl implements UserService {
#Autowired
UserDAO userDAO;
#Override
public List<User> loadUsersByGroupId(long id) {
return userDAO.findAllByGroupId(id);
}
...
UserDAOImpl.java:
#Repository
#Transactional("db1")
public class UserDAOImpl implements UserDAO {
#PersistenceContext(unitName="entityManagerDb1")
private EntityManager em;
#SuppressWarnings("unchecked")
#Override
public List<User> findAllByGroupId(long id) {
Query query = em.createQuery("select distinct u from User u " +
"where u.groupId = :groupId");
query.setParameter("groupId", id);
return query.getResultList();
}
...
app-context.xml (uses annotation-configured JPA, uses two dbs):
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
"
>
<context:annotation-config/>
<context:component-scan base-package="com.example"/>
<!-- db1 -->
<bean id="dataSourceDb1" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/db1?characterEncoding=UTF-8" />
<property name="user" value="root" />
<property name="password" value="root" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="0" />
<property name="preferredTestQuery" value="SELECT 1" />
<property name="idleConnectionTestPeriod" value="600" />
</bean>
<bean id="entityManagerFactoryDb1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="entityManagerDb1"/>
<property name="dataSource" ref="dataSourceDb1"/>
<property name="packagesToScan">
<list>
<value>com.example.domain.db1</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.connection.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.use_outer_join">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
</props>
</property>
</bean>
<!-- Configure transaction manager for JPA -->
<bean id="transactionManagerDb1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryDb1"/>
<qualifier value="db1"/>
</bean>
<!-- db2 -->
<bean id="dataSourceDb2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/db2?characterEncoding=UTF-8" />
<property name="user" value="root" />
<property name="password" value="root" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="0" />
<property name="preferredTestQuery" value="SELECT 1" />
<property name="idleConnectionTestPeriod" value="600" />
</bean>
<bean id="entityManagerFactoryDb2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="entityManagerDb2"/>
<property name="dataSource" ref="dataSourceDb2"/>
<property name="packagesToScan">
<list>
<value>com.example.domain.db2</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.connection.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.use_outer_join">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
</props>
</property>
</bean>
<bean id="transactionManagerDb2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryDb2"/>
<qualifier value="db2"/>
</bean>
<tx:annotation-driven />
</beans>
It drives me crazy that running it inside Eclipse just works as expected. Is the Eclipse export feature somewhat limited? Any hint to another framework for creating runnable jar files?
If it is running from eclipse and not running from the exported jar file, then it is a problem with the export
In the export window there is a checkbox saying Add directory entries that should be checked for component-scan to work
When you run it inside Eclipse all the Spring dependencies and others are loaded into your classpath, but when you export you application as a jar, only your classes get exported, not the dependencies classes.
There are generally two way you can achieve a standlone jar. You can create an 'uber jar' (see Is it possible to create an "uber" jar containing the project classes and the project dependencies as jars with a custom manifest file?) where all you dependency jars got expanded into one single jar. However this method could be risky because if the jars have same file names (eg: same config file inside META-INF) they can overwrite each other
The other more appropriate method is to use maven-dependency-plugin (see dependency:copy) to copy all your dependency into a folder "dependencies". And then run your jar with
java -cp "myjar.jar;dependencies/*" org.mycompany.MainClass
This isn't really a standalone jar, but more a standalone folder. The downside is everytime you add/remove the dependencies (eg: from maven) you have to do the same to your dependencies folder
I'm trying to create a persistance project so it can be re-used by some other projects I'm building on top. I.e it will be used by a web service/spring mvc project and by standalone jar which does some file processing.
I've used hibernate with spring mvc before but never as a standalone executable java jar so I have everything setup and working(application context) :
<?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:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- HIBERNATE -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:spring.properties" />
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.databaseurl}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="acquireIncrement" value="5" />
<property name="idleConnectionTestPeriod" value="60"/>
<property name="maxPoolSize" value="100"/>
<property name="maxStatements" value="50"/>
<property name="minPoolSize" value="10"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list> <value>com/project/utility/persistence/mapping/TestProp.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- END HIBERNATE -->
</beans>
When I test it from main class everything looks ok with mapping/dependencies :
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
}
What I want to do next is to build few dao classes which will get some data and I'd build some interface above that so it can be re-used by both webservice and processing tool as a jar(maven dependency).
In order to build dao classes I need sessionFactory to be != null always. How do I do this?
There are many approaches to this. One solution I use is to use the javax.persistence.PersistenceContext annotation. Spring will respect this annotation and inject a proxy to a thread local EntityManager. Provided your DAO is created by Spring this allows access to the entity manager from within your DAO.
public class DAO {
private EntityManager entityManager;
#PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
#Repository
public class MyDAO {
#Autowired
private SessionFactory sessionFactory;
// ...
}
and add the MyDAO bean to the context XML file, or simply add the following lines to this file:
<context:annotation-config />
<context:component-scan base-package="one.of.the.parent.packages.of.your.dao" />