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
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_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; } }
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 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; } }
Pour la persistence j'utilise la notion de GenericDao :
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 */ }
GenericDao.java
Son implémentation JPA : GenericDaoImpl.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(); }
Pour chacune des entités j'ai une interface Dao qui implémente GenericDao et une classe qui l'implémente et étend GenericDaoImpl
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; } } }
Côté config. j'ai mon fichier persistence.xml
J'ai aussi un fichier database.properties
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>
et enfin mon fichier de conf. Spring :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7db.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, 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 <?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>
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é.
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 !"); } }
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.
Partager