Bonjour à tous,
je suis en train de me former à Spring et JPA et je suis le tutoriel suivant pour commencer : http://loic-frering.developpez.com/tutoriels
J'ai choisi ce tutoriel car je trouve que son architecture est pas mal et qu'il correspond bien à ce que je voudrais faire.
Pourtant, lorsque j'essaie de me faire une classe MOJO qui crée des enregistrements en base (pour son intialisation), le traitement se déroule bien mais rien n'est sauvé en base.
Est-ce que quelqu'un peut me dire où je fais fausse route ?

Mes classes d'entité :

User.java

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package tutojpa.domain.model.base;
 
@Entity
@Table(name = "APP_USER")
public class User implements Serializable
{
	@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "USR_ID", unique = true, nullable = false)
    private Integer id;
 
	@Column(name = "USR_LOGIN", length = 50, nullable = false, unique = true)
	private String login;
 
	@Column(name = "USR_EMAIL", length = 50, nullable = false, unique = true)
	private String email;
 
	@Version
	@Column(name = "USR_VERSION", nullable = false)
	private Integer version;
 
	@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.REMOVE }, mappedBy = "user")
    private List<UserRight> rights = new ArrayList<UserRight>();
 
	public User() {}
	public User(String login, String email) 
	{
		this.login     = login;
		this.email     = email;
	}
 
	/* Getters & Setters */
 
	public List<UserRight> getRights() { return rights; }
	public void setRights(List<UserRight> rights) { this.rights = rights; }
}
Right.java

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package tutojpa.domain.model.base;
 
@Entity
@Table(name = "APP_RIGHT")
public class Right implements Serializable
{
	@Id
	@Column(name = "RIG_CODE", length = 50, unique = true, nullable = false)
	private String code;
 
	@Column(name = "RIG_NAME", length = 100, unique = true, nullable = false)
	private String name;
 
	@Column(name = "RCO_DESCRIPTION", length = 500)
	private String description;
 
	@Version
	@Column(name = "RIG_VERSION", nullable = false)
	private Integer version;
 
	@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "right")
    private List<UserRight> users = new ArrayList<UserRight>();
 
	public Right() {}
	public Right(String code, String name, String description)
	{
		this.code        = code;
		this.name        = name;
		this.description = description;
	}
 
	/* Getters & Setters */
 
	public List<UserRight> getUsers() { return users; }
	public void setUsers(List<UserRight> users) { this.users = users; }
}
UserRight.java

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package tutojpa.domain.model.base;
 
@Entity
@Table(name = "USER_RIGHT")
public class UserRight implements Serializable
{
	@Embeddable
	public static class UserRightPk implements Serializable
	{
		@Column(name = "URI_USER")
		private Integer userId;
 
		@Column(name = "URI_RIGHT")
		private String  rightCode;
 
		public Integer getUserId() { return userId; }
		public void setUserId(Integer userId) { this.userId = userId; }
 
		public String getRightCode() { return rightCode; }
		public void setRightCode(String rightCode) { this.rightCode = rightCode; }
	}
 
	@EmbeddedId
	private UserRightPk pk = new UserRightPk();
	public UserRightPk getPk() { return pk; }
	public void setPk(UserRightPk pk) { this.pk = pk; }
 
	@ManyToOne
	@JoinColumn(name = "URI_USER", insertable = false, updatable = false)
	private User user;
 
	@ManyToOne
	@JoinColumn(name = "URI_RIGHT", insertable = false, updatable = false)
	private Right right;
 
	@Version
	@Column(name = "URI_VERSION", nullable = false)
    private Integer version;
 
	public UserRight(User user, Right right)
	{
		getPk().setUserId   (user.getId());
		getPk().setRightCode(right.getCode());
 
		this.setUser(user);
		this.setRight(right);
 
		user.addRight(this);
		right.addUser(this);
	}
 
	/* Getters & Setters */
}
Pour la persistence j'utilise la notion de GenericDao :

GenericDao.java

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
package tutojpa.domain.dao;
 
public interface GenericDao<T, PK> 
{
	public void persist(T object);
	public List<T> findAll();
}
Son implémentation JPA : GenericDaoImpl.java

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package tutojpa.domain.dao.jpa;
 
@Repository("genericDao")
public abstract class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK>
{
	protected static final Logger log = Logger.getLogger(GenericDaoImpl.class);
 
	@PersistenceContext
	protected EntityManager em;
 
	protected Class<T> type = null;
 
	protected GenericDaoImpl() 
	{
		this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
 
	public void persist(T object) 
	{
		log.debug("Persisting " + type.getSimpleName() + " instance");
		try 
		{
			em.persist(object);
			log.debug("persist successful");
		} 
		catch (RuntimeException re) 
		{ 
			log.error("persist failed", re);
			throw re;
		}
	}
	public List<T> findAll() 
	{
		log.debug("Getting all " + type.getSimpleName() + " instances");
		try { return (List<T>)em.createQuery("SELECT x FROM " + type.getSimpleName() + " x").getResultList(); } 
		catch (RuntimeException re) 
		{
			log.error("findAll failed", re);
			throw re;
		}
	}
}
Pour chacune des entités j'ai une interface Dao qui implémente GenericDao et une classe qui l'implémente et étend GenericDaoImpl

Côté config. j'ai mon fichier persistence.xml

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
    </persistence-unit>
</persistence>
J'ai aussi un fichier database.properties

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
db.connection.driver=com.mysql.jdbc.Driver
db.connection.url=jdbc:mysql://localhost:3306/tutojpa
db.connection.username=tutojpa
db.connection.password=tutojpa
jpa.dialect=org.springframework.orm.jpa.vendor.HibernateJpaDialect
jpa.vendor.adapter=HibernateJpaVendorAdapter
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
et enfin mon fichier de conf. Spring :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
<?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:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 
 
	<!-- Placholders to import inherited variables -->
	<bean id="project-properties"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="ignoreUnresolvablePlaceholders">
			<value>true</value>
		</property>
		<property name="locations">
			<list>
				<value>classpath*:database.properties</value>
			</list>
		</property>
	</bean>
 
	<!-- post-processors for all standard config annotations -->
	<context:annotation-config />
	<context:component-scan base-package="tutojpa" />
 
	<!-- Exception translation bean post processor -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
 
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${db.connection.driver}" />
		<property name="url" value="${db.connection.url}" />
		<property name="username" value="${db.connection.username}" />
		<property name="password" value="${db.connection.password}" />
	</bean>
 
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="jpaDialect">
			<bean class="${jpa.dialect}" />
		</property>
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.${jpa.vendor.adapter}">
				<property name="databasePlatform" value="${hibernate.dialect}" />
				<property name="showSql" value="false" />
				<property name="generateDdl" value="false" />
			</bean>
		</property>
	</bean>
 
	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
 
	<!-- enable the configuration of transactional behavior based on annotations -->
	<tx:annotation-driven transaction-manager="txManager" />
</beans>
Et enfin, j'ai ma classe de test qui ne fonctionne pas :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package tutojpa.domain.utils;
 
public class InitDb 
{
	public static final Logger log = Logger.getLogger(InitDb.class);
 
	public static void main(String[] args) 
	{
		log.info("Initializing database");
 
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		EntityManagerFactory emf = (EntityManagerFactory)ctx.getBean("entityManagerFactory");
		EntityManager em = emf.createEntityManager();
 
		UserDao      userDao      = (UserDao)ctx.getBean("userDao");
		RightDao     rightDao     = (RightDao)ctx.getBean("rightDao");
		UserRightDao userRightDao = (UserRightDao)ctx.getBean("userRightDao");
 
		// Begin Transaction
		EntityTransaction tx = em.getTransaction();
		tx.begin();
 
		Query query;
		query = em.createNativeQuery("delete from USER_RIGHT");
		query.executeUpdate();
		query = em.createNativeQuery("delete from APP_USER");
		query.executeUpdate();
		query = em.createNativeQuery("delete from APP_RIGHT");
		query.executeUpdate();
 
		// Create Rights
		Right r0   = new Right("ADMIN", "Administrator", "Administrates the entire application");
		rightDao.persist(r0);
 
		// Create Users
		User u0 = new User("monlogin", "mon@mail.fr");
		userDao.persist(u0);
 
		// Associates User and Right
		UserRight ur0 = new UserRight(u0, r0);
		userRightDao.persist(ur0);
 
		// Listing
		log.debug("[User]");
		for (Object u : em.createQuery("select u from User u").getResultList())
			log.debug("\t" + u);
 
		log.debug("[Right]");
		for (Object r : em.createQuery("select r from Right r").getResultList())
			log.debug("\t" + r);
 
		log.debug("[User_Right]");
		for (Object ur : em.createQuery("select ur from UserRight ur").getResultList())
			log.debug("\t" + ur);
 
		// End Transaction
		tx.commit();
 
		// End Persistence Context
		em.close();
		emf.close();
 
		log.info("Database Init Done !");
	}
}
La classe s'exécute sans erreur et pourtant les listings ne remontent aucune donnée. J'ai vérifié en base et il n'y a effectivement rien de sauvé.
Point important, si dans cette classe de test je remplace l'utilisation des Dao par l'entityManager em, ça fonctionne.
Je pense que le souci vient de l'initialisation du contexte Spring mais je ne sais pas comment faire pour arranger la situation.
Si quelqu'un a une idée je suis preneur.
D'avance merci.