Bonjour,
Je bloque depuis quelques jours sur un des concepts de base de Spring. Je suis un nouvel utilisateur, qui doit effectuer un projet avec ce framework, et je m'avoue un peu perdu.
J'ai crée des classes Métiers grâce à la génération automatique disponible dans Netbeans. Voici par exemple une classe Compte :
Ensuite, j'ai crée une classe DAO, qui permet de spécifier pour toutes ses classes filles la dataSource et le jdbcTemplate :
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
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 package horens.domain.models.auth; import java.io.Serializable; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.xml.bind.annotation.XmlRootElement; @Entity @Table(name = "auth_compte") @XmlRootElement @NamedQueries({ @NamedQuery(name = "AuthCompte.findAll", query = "SELECT a FROM Compte a"), @NamedQuery(name = "AuthCompte.findByLogin", query = "SELECT a FROM Compte a WHERE a.login = :login"), @NamedQuery(name = "AuthCompte.findByPassword", query = "SELECT a FROM Compte a WHERE a.password = :password"), @NamedQuery(name = "AuthCompte.findByEmail", query = "SELECT a FROM Compte a WHERE a.email = :email"), @NamedQuery(name = "AuthCompte.findByNom", query = "SELECT a FROM Compte a WHERE a.nom = :nom"), @NamedQuery(name = "AuthCompte.findByPrenom", query = "SELECT a FROM Compte a WHERE a.prenom = :prenom"), @NamedQuery(name = "AuthCompte.findByDerniereConnexion", query = "SELECT a FROM Compte a WHERE a.derniereConnexion = :derniereConnexion")}) public class Compte implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "login") private String login; @Basic(optional = false) @Column(name = "password") private String password; @Basic(optional = false) @Column(name = "email") private String email; @Basic(optional = false) @Column(name = "nom") private String nom; @Basic(optional = false) @Column(name = "prenom") private String prenom; @Column(name = "derniereConnexion") @Temporal(TemporalType.DATE) private Date derniereConnexion; @JoinColumn(name = "typeProfil", referencedColumnName = "idProfil") @ManyToOne(optional = false) private Profil typeProfil; public Compte() { } public Compte(String login) { this.login = login; } public Compte(String login, String password, String email, String nom, String prenom) { this.login = login; this.password = password; this.email = email; this.nom = nom; this.prenom = prenom; } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getPrenom() { return prenom; } public void setPrenom(String prenom) { this.prenom = prenom; } public Date getDerniereConnexion() { return derniereConnexion; } public void setDerniereConnexion(Date derniereConnexion) { this.derniereConnexion = derniereConnexion; } public Profil getTypeProfil() { return typeProfil; } public void setTypeProfil(Profil typeProfil) { this.typeProfil = typeProfil; } @Override public int hashCode() { int hash = 0; hash += (login != null ? login.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { if (!(object instanceof Compte)) { return false; } Compte other = (Compte) object; if ((this.login == null && other.login != null) || (this.login != null && !this.login.equals(other.login))) { return false; } return true; } @Override public String toString() { return "horens.domain.models.AuthCompte[ login=" + login + " ]"; } }
Enfin, pour terminer mon exemple, voilà la classe DAO, associé à la classe Compte donnée plus haut :
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 package horens.domain.dao; import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.orm.hibernate3.HibernateTemplate; public abstract class DAO<T> { protected DataSource dataSource; protected SimpleJdbcTemplate jdbcTpl; private HibernateTemplate hibernateTemplate; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; jdbcTpl = new SimpleJdbcTemplate(dataSource); } public void setSessionFactory(SessionFactory sessionFactory) { this.hibernateTemplate = new HibernateTemplate(sessionFactory); } public abstract boolean create(T obj); public abstract boolean delete(T obj); public abstract boolean update(T obj); public abstract T get(int id); }
Toutes ces classes compilent. Je souhaite désormais pouvoir appeler la classe DAO facilement depuis une servlet. Et c'est là que le problème survient. J'ai suivi sur le net plusieurs manuels, docs et tutos... Chaque auteur avait sa version, et ça m'a plus embrouillé qu'autre chose. Au final, dans mon applicationContext.xml, en plus du dataSource et du sessionFactory j'ai ceci :
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 horens.domain.dao.auth; import horens.domain.dao.DAO; import horens.domain.models.auth.Compte; import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; public class CompteDAO extends DAO<Compte> implements Serializable { public Collection getAll() { return jdbcTpl.query("SELECT * FROM auth_compte", new CompteMapper()); } @Override public boolean create(Compte obj) { jdbcTpl.update("INSERT INTO auth_compte(login, password, email, typeProfil, nom, prenom) VALUES(?,?,?,?,?,?)", obj.getLogin(), obj.getPassword(), obj.getEmail(), obj.getTypeProfil(), obj.getNom(), obj.getPrenom() ); return true; } @Override public boolean delete(Compte obj) { jdbcTpl.update("DELETE FROM auth_compte WHERE login = ?", obj.getLogin()); return true; } @Override public boolean update(Compte obj) { throw new UnsupportedOperationException("Not supported yet."); } @Override public Compte get(int id) { throw new UnsupportedOperationException("Not supported yet."); } public Compte get(String login) { return (Compte) this.jdbcTpl.queryForObject( "SELECT * FROM auth_compte WHERE login = ?", new CompteMapper(), login); } private static final class CompteMapper implements RowMapper { @Override public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new Compte(rs.getString("login"), rs.getString("password"), rs.getString("email"), rs.getString("nom"), rs.getString("prenom") ); } } }
Or quand j'essayes d'appeler compteDao dans une servlet, ça en marche pas (NullPointerException quand je visite la page). Voici le code de ma servlet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 <bean id="daoBase" class="horens.models.dao.DAO" abstract="true"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="compteDao" class="horens.domain.dao.auth.CompteDAO" parent="daoBase"/>
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 package horens.servlets.consultation; import horens.domain.dao.auth.CompteDAO; import horens.domain.models.auth.Compte; import java.io.IOException; import java.sql.SQLException; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @WebServlet(name = "VueCompteServlet", urlPatterns={"/VueCompteServlet"}) public class VueCompteServlet extends HttpServlet { @Autowired private CompteDAO compteDAO; public void setCompteDAO(CompteDAO compteDAO) { this.compteDAO = compteDAO; } public CompteDAO getCompteDAO() { return this.compteDAO; } /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Ref dans l'url String login = request.getParameter("login"); // Récupération d'un compte Compte cpt = compteDAO.get(login); request.setAttribute("cpt", cpt); request.getRequestDispatcher("WEB-INF/jsp/compte/vueDetaillee.jsp").forward(request, response); } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> }
... et je ne comprends pas pourquoi. Pouvez-vous me donner quelques pistes ? Comment agit l'annotation @Autowired ?
J'ai vu dans de nombreux tutos la déclaration d'une couche "Service", qui, à mon impression, reprend en grande partie les actions faites par le DAO. A quoi sert cette couche ?
Merci d'avance, et bonnes fêtes.
Partager