Bonjour, je me lance dans une appli web bien construite en utilisant au maximum jee6, et en évitant les outils comme spring hibernate ou autre. J'utilise des classes génériques pour mes entités et les accès aux bases de données avec ejb. La base de données étant derrière glassfish avec un appel jndi.

Pour l'instant je n'ai pas réussi à faire fonctionner un test et voir si ca fonctionne. Je voudrais vous demander si les classes ont l'air correctes et quel est le moyen le plus simple pour vérifier si tout fonctionne. (cactus ? junit ?)

Chaque entité doit pouvoir renvoyer la clé primaire typée d'où le getPK(), mais je ne sais pas si c'est une bonne idée...

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
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
 
@MappedSuperclass
public abstract class GenericEntity<PK> {
 
    public abstract PK getPK();
    @Column(nullable = false)
    @Version
    private Integer version;
 
    public Integer getVersion() {
        return version;
    }
 
    public void setVersion(Integer version) {
        this.version = version;
    }
}
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
@Entity
public class Utilisateur extends GenericEntity<Long> implements Serializable {
 
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String login;
    private String password;
 
    public Utilisateur() {
    }
 
    public Utilisateur(String login, String password) {
        this.login = login;
        this.password = password;
    }
 
    {getter/setter equals hashcode tostring}
 
    @Override
    public Long getPK() {
        return id;
    }
}
L'injection de l'emf se fait-elle dans la classe générique ou faut-il le placer dans chaque implémentation ? idem pour les annotations de transaction
Faut-il placer @Stateless dans la classe générique ?

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
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public abstract class GenericManager<T extends GenericEntity, PK extends Serializable> implements iGenericManager<T, PK> {
 
    /**
     * injected JPA entity manager
     */
    @PersistenceUnit(unitName = "espheria_PU")
    private EntityManagerFactory emf;
   // @Resource
  //  private SessionContext sc;
 
    public GenericManager() {
    }
 
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
 
    /**    
     * returns class of T
     * @return
     */
    // @SuppressWarnings("unchecked")
    private Class<T> getEntityClass() {
        ParameterizedType ptype = (ParameterizedType) getClass().getGenericSuperclass();
        return (Class<T>) ptype.getActualTypeArguments()[0];
    }
 
    /**
     * creates entity
     *
     * @param obj
     * @return
     * @throws CreateException
     */
    public void create(T obj) throws RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.persist(obj);
        } catch (Exception ex) {
//            try {
//                sc.setRollbackOnly();
//            } catch (Exception re) {
//                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
//            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }
// Autres opérations de CRUD et autres
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
@Stateless
public class UtilisateurManager extends GenericManager<Utilisateur, Long> implements iUtilisateurManager{
 
    public UtilisateurManager() {
        super();
    }
 
}
Les interfaces pour le moment vides :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
public interface iGenericManager<T extends GenericEntity, PK extends Serializable> {
 
}
 
public interface iUtilisateurManager extends iGenericManager<Utilisateur,Long> {
 
}
Et donc si vous me lisez toujours, je cherche à tester mes managers, j'ai vu qu'avec glassfish3.1 on pouvait l'embarquer pour les tests, mais j'ai une erreur de cast :

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
package fr.espheria.ejb;
 
import fr.espheria.domain.Utilisateur;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
 
/**
 *
 * @author Gab'z
 */
public class UtilisateurManagerTest {
 
    private static EJBContainer ec;
    private static Context ctx;
 
    @BeforeClass
    public static void initContainer() throws Exception {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put(EJBContainer.MODULES, new File[]{new File("target/classes")});
        props.put(EJBContainer.APP_NAME, "test");
        props.put(EJBContainer.PROVIDER, "org.glassfish.ejb.embedded.EJBContainerProviderImpl");
 
        ec = EJBContainer.createEJBContainer(props);
        ctx = ec.getContext();
    }
 
    @AfterClass
    public static void closeContainer() throws Exception {
        if (ec != null) {
            ec.close();
        }
        if (ctx != null) {
            ctx.close();
        }
    }
 
    @Test
    public void createFormation() throws Exception {
        Utilisateur user = new Utilisateur();
        user.setLogin("Arnaud");
        user.setPassword("mdp");
        System.out.println("ERREUR JUSTE APRES CETTE LIGNE");
        UtilisateurManager um = (UtilisateurManager) ctx.lookup("java:global/test/classes/UtilisateurManager");
        um.create(user);
        assertNotNull(user.getId());
 
    }
Et ici l'erreur du test :
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
-------------------------------------------------------------------------------
Test set: fr.espheria.ejb.UtilisateurManagerTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 5.186 sec <<< FAILURE!
createFormation(fr.espheria.ejb.UtilisateurManagerTest)  Time elapsed: 0.015 sec  <<< ERROR!
java.lang.ClassCastException: $Proxy104 cannot be cast to fr.espheria.ejb.UtilisateurManager
	at fr.espheria.ejb.UtilisateurManagerTest.createFormation(UtilisateurManagerTest.java:54)
	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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
	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.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
	at $Proxy0.invoke(Unknown Source)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)