Création auto de la base en JPA
Hello !
Je galère énormément à faire fonctionner une appli reposant sur Spring - JPA - Hibernate - HSQL. Notamment, la création du schéma de la base que je croyais fait automatiquement, n'est pas accompli. Ce qui fait que lors de mes appels DAO ca explose.
Voila l'objet métier persisté:
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| @Entity
public class Portfolio {
@Id
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Stock> stocks;
// Accesseur classiques
} |
Et le DAO ainsi:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
@Transactional
public class GenericDaoJpaImpl<T, PK extends Serializable> implements
GenericDao<T, PK> {
private Class<? extends T> clazz;
private EntityManager entityManager;
public GenericDaoJpaImpl(Class<? extends T> clazz) {
super();
this.clazz = clazz;
}
// Spring will inject this:
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.entityManager = em;
}
public EntityManager getEntityManager() {
return entityManager;
}
public void create(T newInstance) throws DAOException {
getEntityManager().persist(newInstance);
}
public void delete(PK id) throws DAOException {
getEntityManager().remove(read(id));
}
public void delete(T persistentObject) throws DAOException {
getEntityManager().remove(persistentObject);
}
public boolean exists(PK id) throws DAOException {
return getEntityManager().contains(id);
}
public T read(PK id) throws DAOException {
return getEntityManager().find(getClazz(), id);
}
@SuppressWarnings("unchecked")
public List<T> readAll() throws DAOException {
String entityName = getEntityName();
return (List<T>) getEntityManager().createQuery(
"SELECT instance FROM " + entityName + " instance");
}
public void update(T transientObject) throws DAOException {
getEntityManager().persist(transientObject);
}
public final Class<? extends T> getClazz() {
return clazz;
}
public String getEntityName() {
Entity entity = (Entity) getClazz().getAnnotation(Entity.class);
if (entity == null) {
return getClazz().getSimpleName();
}
String entityName = entity.name();
if (entityName == null) {
return getClazz().getSimpleName();
} else if (!(entityName.length() > 0)) {
return getClazz().getSimpleName();
} else {
return entityName;
}
}
@SuppressWarnings("unchecked")
public List<T> findBy(String property, Object value) throws DAOException {
String entityName = getEntityName();
return (List<T>) getEntityManager().createQuery(
"SELECT instance FROM " + entityName + " instance");
}
} |
La configuration Spring est la suivante, notez que j'utilise au max les annotations (transaction, entity, etc).
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>jdbc-properties.xml</value>
</property>
</bean>
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"
id="persistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<!-- The entity manager factory declaration -->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect"/>
</bean>
</property>
<property name="persistenceUnitName" value="MainPU"/>
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="dataSource" ref="dataSource"/>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/>
</property>
</bean>
<!-- The data source declaration -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- The transaction manager declaration -->
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> </bean>
<!--
Tell Spring to use its declarative @Transaction annotation.
-->
<tx:annotation-driven/>
<!--
Makes Spring aware to the @PersistenceContext/@PersistenceUnit annotation.
-->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.ccl.portfolioptim.server.manager.stock.YahooDataloaderImpl" id="dataLoaderMgr">
<property name="urlPattern">
<value>
<![CDATA[http://ichart.yahoo.com/table.csv?s={0}&d={4}&e={5}&f={6}&g=d&a={1}&b={2}&c={3}&ignore=.xml]]>
</value>
</property>
<property name="properties">
<props/>
</property>
</bean>
<!--
DAO
-->
<bean class="org.ccl.portfolioptim.server.dao.GenericDaoJpaImpl" id="stockDao">
<constructor-arg>
<value>org.ccl.portfolioptim.server.domain.stock.Stock</value>
</constructor-arg>
</bean>
<bean class="org.ccl.portfolioptim.server.dao.GenericDaoJpaImpl" id="priceDao">
<constructor-arg>
<value>org.ccl.portfolioptim.server.domain.stock.Price</value>
</constructor-arg>
</bean>
<bean class="org.ccl.portfolioptim.server.dao.GenericDaoJpaImpl" id="marketDao">
<constructor-arg>
<value>org.ccl.portfolioptim.server.domain.stock.Market</value>
</constructor-arg>
</bean>
<bean class="org.ccl.portfolioptim.server.dao.GenericDaoJpaImpl" id="portfolioDao">
<constructor-arg>
<value>org.ccl.portfolioptim.server.domain.portfolio.Portfolio</value>
</constructor-arg>
</bean> |
Ainsi que jdbc-properties.xml
Code:
1 2 3 4 5 6 7 8 9
|
<properties>
<comment>Configuration file for the JDBC driver.</comment>
<entry key="jdbc.driverClassName">org.hsqldb.jdbcDriver</entry>
<entry key="jdbc.url">jdbc:hsqldb:file:///C:/temp/portfolio.db</entry>
<entry key="jdbc.username">sa</entry>
<entry key="jdbc.password"/>
</properties> |
et persistence.xml
Code:
1 2 3 4 5 6 7
| <persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="MainPU" transaction-type="RESOURCE_LOCAL"> </persistence-unit>
</persistence> |
un appel à readAll() du DAO m'envoie l'exception suivante :
Code:
1 2
|
java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: Portfolio is not mapped [SELECT instance FROM Portfolio instance] |
Et effectivement la table associée n'existe pas dans la base. Pour quelle raison la structure de la base n'est pas créé automatiquement ?
Merci !