Bonjour/bonsoir
j'ai une requête nommé sur un champ pouvant être nul or à l’exécution je m'attend à récupérer tous les enregistrements dont la valeur du champ est nul or ce n'est pas le cas, le résultat de la requête ne me ramène aucun élément.
Il semble que jpa avec jpql ne gère pas dans les NamedQuery qu'on lui passe un paramètre à null, comment gérer cette situation sans si possible avoir recours à des hack de manipulation de String?

entité
Code java : 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package kn.organization.basis.domain;
 
import java.io.Serializable;
import java.util.Date;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
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.persistence.Version;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
 
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.annotations.Index;
 
/**
 * @author Khaled.Noordin
 */
@Entity
@Table(name = "user_")
@NamedQueries({
 @NamedQuery(name = "User.findByAccount", query = "select u from User u where u.account = :account"),
 @NamedQuery(name = "User.findByFirstName", query = "select u from User u where u.firstName = :firstName"),
 @NamedQuery(name = "User.findByFirstNameLike", query = "select u from User u where u.firstName like :firstName"),
 @NamedQuery(name = "User.findBySecondName", query = "select u from User u where u.secondName = :secondName"),
 @NamedQuery(name = "User.findBySecondNameLike", query = "select u from User u where u.secondName like :secondName"),
 @NamedQuery(name = "User.findByLastName", query = "select u from User u where u.lastName = :lastName"),
 @NamedQuery(name = "User.findByLastNameLike", query = "select u from User u where u.lastName like :lastName"),
 @NamedQuery(name = "User.findBetweenRegisteredDates", query = "select u from User u where u.registeredDate between :date1 and :date2 order by u.id asc"),
 @NamedQuery(name = "User.findBetweenDatesOfBirth", query = "select u from User u where u.dateOfBirth between :date1 and :date2"),
 @NamedQuery(name = "User.findByGender", query = "select u from User u where u.gender = :gender")
})
@XmlRootElement
public class User implements Serializable {
 
 private static final long serialVersionUID = 5182195208706551452L;
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "user_id")
 private Long id;
 @Version
 private Integer version;
 @ManyToOne
 @JoinColumn(unique = true, name = "account_id")
 @NotNull
 private Account account;
 @NotNull
 @Index(name = "idx_user_firstname")
 @Column(name = "first_name")
 private String firstName;
 @Index(name = "idx_user_secondname")
 @Column(name = "second_name")
 private String secondName;
 @NotNull
 @Index(name = "idx_user_lastname")
 @Column(name = "last_name")
 private String lastName;
 @Temporal(value = TemporalType.TIMESTAMP)
 @NotNull
 @Past
 @Index(name = "idx_user_birthdate")
 @Column(name = "date_of_birth")
 private Date dateOfBirth;
 @Temporal(value = TemporalType.TIMESTAMP)
 @NotNull
 @Index(name = "idx_user_registered_date")
 @Column(name = "registered_date")
 private Date registeredDate;
 @NotNull
 @Index(name = "idx_user_gender")
 @Column(name = "gender", columnDefinition = "Boolean")
 private Boolean gender;
 
 public User() {
  this.id = null;
  this.version = null;
  this.account = null;
  this.firstName = null;
  this.secondName = null;
  this.lastName = null;
  this.dateOfBirth = null;
  this.registeredDate = null;
  this.gender = null;
 }
 
 public User(Account account,
         String firstName,
         String lastName,
         Date dateOfBirth,
         Date registeredDate,
         Boolean gender) {
  this();
  this.account = account;
  this.firstName = firstName;
  this.lastName = lastName;
  this.dateOfBirth = dateOfBirth;
  this.registeredDate = registeredDate;
  this.gender = gender;
 }
 
 public User(Account account,
         String firstName,
         String secondName,
         String lastName,
         Date dateOfBirth,
         Date registeredDate,
         Boolean gender) {
  this(account, firstName, lastName, dateOfBirth, registeredDate, gender);
  this.secondName = secondName;
 }
 
 public Account getAccount() {
  return account;
 }
 
 public void setAccount(Account account) {
  this.account = account;
 }
 
 public Date getDateOfBirth() {
  return dateOfBirth;
 }
 
 public void setDateOfBirth(Date dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }
 
 public String getFirstName() {
  return firstName;
 }
 
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 
 public Boolean getGender() {
  return gender;
 }
 
 public void setGender(Boolean gender) {
  this.gender = gender;
 }
 
 public Long getId() {
  return id;
 }
 
 public void setId(Long id) {
  this.id = id;
 }
 
 public String getLastName() {
  return lastName;
 }
 
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 
 public Date getRegisteredDate() {
  return registeredDate;
 }
 
 public void setRegisteredDate(Date registeredDate) {
  this.registeredDate = registeredDate;
 }
 
 public String getSecondName() {
  return secondName;
 }
 
 public void setSecondName(String secondName) {
  this.secondName = secondName;
 }
 
 public Integer getVersion() {
  return version;
 }
 
 public void setVersion(Integer version) {
  this.version = version;
 }
 
 @Override
 public String toString() {
  return ToStringBuilder.reflectionToString(
          this,
          ToStringStyle.SHORT_PREFIX_STYLE);
 }
 
 /**
  * 
  * @return 
  */
 @Override
 public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(
          this,
          new String[]{
           "id",
           "version"
          });
 }
 
 /**
  * @param object
  * @return 
  */
 @Override
 public boolean equals(Object object) {
  return ( !( object instanceof User )
          || object == null ) ? false
          : EqualsBuilder.reflectionEquals(
          this,
          object,
          new String[]{
           "id",
           "version",
           "dateOfBirth",
           "registeredDate"
          })
          && ( (User) object ).registeredDate.getTime()
          == this.registeredDate.getTime()
          && ( (User) object ).dateOfBirth.getTime()
          == this.dateOfBirth.getTime();
 }
}

méthode de requête de la façade générique de dao
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 public List<T> findWithNamedQuery(
         String stringQuery,
         Map<String, Object> params) {
  Query q = getEntityManager().
          createNamedQuery(stringQuery);
  Iterator it = params.entrySet().iterator();
  while (it.hasNext()) {
   Map.Entry<String, Object> pairs = (Map.Entry) it.next();
   q.setParameter(pairs.getKey(), pairs.getValue());
  }
  return (List<T>) q.getResultList();
 }

methode du dao de mon entité
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 @Override
 public List<User> findBySecondName(final String secondName) {
  return super.findWithNamedQuery("User.findBySecondName",
          new HashMap<String, Object>() {
 
           private static final long serialVersionUID = 4134613174905997704L;
 
           {
            put("secondName", secondName);
           }
          });
 }

test de ma méthode
Code java : 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
 @Test
 public void testFindBySecondName_String() {
  System.out.println("\n\tfindBySecondName_String");
  Boolean assertResult = Boolean.TRUE;
  String secondName = null;
  List<User> resultList = userDao.findBySecondName(secondName);
  System.out.println(resultList.size());
  List<User> expResult = new ArrayList<User>() {
 
   {
    for (int i = 0, length = EXPECTED_RESULT_LIST.size();
            i < length; i++) {
     add(EXPECTED_RESULT_LIST.get(i));
    }
   }
  };
  for (int i = 0, length = expResult.size();
          i < length; i++) {
   if (assertResult) {
    assertResult = expResult.get(i).
            equals(resultList.get(i))
            ? Boolean.TRUE
            : Boolean.FALSE;
   } else {
    break;
   }
  }
  assertTrue(assertResult);
  assertEquals(resultList.size(), 20);
  assertEquals(expResult.size(), resultList.size());
 }

trace d'erreur
Testcase: testFindBySecondName_String(kn.organization.basis.domain.dao.jpa.AbstractUserDaoJpaTest): Caused an ERROR
Index: 0, Size: 0
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.RangeCheck(ArrayList.java:547 at java.util.ArrayList.get(ArrayList.java:322)
)
at kn.organization.basis.domain.dao.jpa.AbstractUserDaoJpaTest.testFindBySecondName_String(AbstractUserDaoJpaTest.java:398)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.
Test kn.organization.basis.domain.dao.jpa.AbstractUserDaoJpaTest FAILED
le code est testable dans la mesure ou je n'ai pas trouvé la solution en telechargeant le projet ici aucun besoin d'installation de server ou base de données tout se fait en memoire, pour voir un plus du code les sources sont visible la