Pages enfant
  • 3.3.4 Accès aux données avec JPA

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.

...

La déclaration se fait dans le fichier resources/properties/dao/dao.xml :

Bloc de code
 <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="${datasource.bean}" />
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
		<property name="persistenceXmlLocation" value="classpath:/properties/dao/persistence.xml" />
		<property name="jpaProperties" ref="jpaProperties" />
	</bean>

	<bean id="JDBCDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close"
		lazy-init="true">
		<property name="driverClassName" value="${jdbc.connection.driver_class}" />
		<property name="maxActive" value="100" />
		<property name="maxIdle" value="30" />
		<property name="maxWait" value="100" />
		<property name="url" value="${jdbc.connection.url}" />
		<property name="username" value="${jdbc.connection.username}" />
		<property name="password" value="${jdbc.connection.password}" />
	</bean>

	<jee:jndi-lookup id="JNDIDataSource" jndi-name="${jndi.datasource}" lookup-on-startup="false" expected-type="javax.sql.DataSource"/>

	<bean id="jpaVendorAdapter"
		class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="showSql" value="true" />
		<property name="generateDdl" value="true" />
		<property name="database" value="${jpa.database.type}" />
	</bean>

	<util:properties id="jpaProperties">
		<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
		<prop key="hibernate.cache.use_query_cache">false</prop>
		<prop key="hibernate.cache.use_second_level_cache">false</prop>
	</util:properties>

	<bean id="daoService" class="org.esupportail.example.dao.JPADaoServiceImpl"
		lazy-init="true">
	</bean>

...

Si on souhaite accéder à n bases de données il est possible de déclarer n gestionnaires d'entités.

Avertissement

TODO

ICI ????

...

  • Le développeur a la totale maîtrise de la base de données, c'est lui qui la fait évoluer en fonction des besoins de son application. Il utilisera dans ce cas l'implémentation UgradableHibernateDatabaseManagerImpl. Cette implémentation lui permettra de faire évoluer la structure de sa base de données en modifiant son mapping, de manière automatique sans même toucher au code SQL.
  • Le développeur n'a pas la maîtrise de la base de données : il s'agit d'une base de données institutionnelle, ou bien encore d'une base maîtrisée par une autre application. Il utilisera dans ce cas l'implémentation BasicHibernateDatabaseManagerImpl, et devra alors faire coller son mapping aux structures de la base de données.

Mapping avec la base de données

...

Bloc de code
@Entity
public class User implements Serializable {

	/**
	 * Id of the user.
	 */
	@Id
	private String id;

    /**
	 * Display Name of the user.
	 */
    private String displayName;

    /**
	 * True for administrators.
	 */
    private boolean admin;

    /**
     * The prefered language.
     */
    private String language;

    /**
     * information recorded during database insert
     * used in esup-example to illustrate open session in view mechanism
     */
    @OneToMany(cascade={CascadeType.ALL})
    private List<Information> informations;

Explications :

  • L'annotation @Entity précise que la Classe est une entité à persister. Par défaut tous les propriétés de la classe seront persistées. Un règle de nommage par défaut (si pas de présence d'une annotation sur la propriété pour une déclaration explicite) sera appliquée afin de déterminer le nom de la colonne en base de données.
  • L'annotation @Id précise que cette propriété sera utilisée comme clé primaire de la table dans la base de données.
    • Note : En JPA comme en Hibernate il est recommandé d'utiliser une clé physique (celle qui sera utilisée comme clé primaire de la table dans la base de données) différente de la clé métier utilisé par l'application. Il est aussi recommandé de créer des méthodes equals et hcode basée sur la clé métier.
      Ici User est un cas particulier où la clé physique est aussi la clé métier dans la mesure où la clé n'est pas calculée (non utilisation de l'annotation @GeneratedValue en plus de*@Id*). Néanmoins cette pratique reste déconseillée car si nous devions faire évoluer notre besoin métier (par exemple utiliser une autre propriété de la classe -en plus de id- en tant que clé métier) nous n'arriverions pas à le faire (la contrainte d'unicité physique portant exclusivement sur id)
  • L'annotation
    Pas de format
    @OneToMany(cascade={CascadeType.ALL})
    défini une association un à plusieurs. La cascade permet de préciser que si on fait une opération, typiquement un effacement, sur le père alors elle sera répercutée sur les enfants.

...