Avatar billede kernelx Juniormester
16. februar 2013 - 14:19 Der er 4 kommentarer og
1 løsning

JPA2 og CriteriaBuilder.nullif

Hej,

jeg har en JPA2 entity:
-----------------------
@Entity
@Table(name = "FOO")
public class FooEntity {

    @Column(name = "ID")
    @Id
    private Long id;

    @Column(name = "SOME_TEXT")
    private String someText;

    // getters and setters
}
-----------------------

Så har jeg en JPA2 Criteria Query:
----------------------------------
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<FooEntity> query = cb.createQuery(FooEntity.class);
Root<FooEntity> foo = query.from(FooEntity.class);
Expression<?> someTextOrNullExpression = cb.nullif(foo.get(FooEntity_someText), "test");
query.select(foo);
TypedQuery<FooEntity> typedQuery = em.createQuery(query);
List<FooEntity> resultList = typedQuery.getResultList();
for (FooEntity fooEntity : resultList) {
    System.out.println(fooEntity.getId() + "\t| " + fooEntity.getSomeText());
}
----------------------------------

Output er:
----------------------------------
1      | abc
2      | test
3      | def
----------------------------------

Er det muligt at blande min someTextOrNullExpression med mit query.select(), sådan at jeg
for følgende output uden at bruge Tuple query eller constructor expression i min criteria query?
----------------------------------
1      | abc
2      | null
3      | def
----------------------------------

Hvis ja, hvordan?

Mange tak for hjelp!

med venlig hilsen
KernelX
Avatar billede arne_v Ekspert
17. februar 2013 - 21:54 #1
At aendre i de outouttede vaerdier er ikke et kriterie, saa jeg tror at kriterie er en blindgyde for problemet.

En loesning var udover getSomeText at have en getSomeTextModified der returnerer hvad du vil have.

En anden loesning var at lave en @PostLoad metode som opdaterer someText som oensket. Men her skal du taenke paa hvad du vil have der sker naar der opdateres igen!

Derover findes der forskellige provider specifikke loesninger. Hibernate har bl.a. en @Formula. Men hvis jeg husker rigtigt saa bruger du ikke Hibernate.
Avatar billede kernelx Juniormester
20. februar 2013 - 21:00 #2
Mange tak!
Husk at skrive et eller andet som svar.
Avatar billede arne_v Ekspert
20. februar 2013 - 23:18 #3
Var der noget af det som kunne bruges?
Avatar billede kernelx Juniormester
22. februar 2013 - 17:56 #4
Jeg kunne bruge svaret "nej, det er ikke muligt" :-)
Hvis du ikke kender en løsning, så er der ingen, som gør :-)

Med @PostLoad bliver jeg nødt til at lave en ny Tuple query, som finder ud af, hvilke fields der skal sættes på null.
Da @PostLoad bliver udført for alle fundede entities bliver jeg så nødt til at lave en Tuple query per result entity.

Jeg kan kun bruge JPA2 standard. Så det kan være, at en Java EE 6 Container bruger Hibernate, men en anden OpenJPA og så videre.

Jeg tror, at jeg laver en Tuple query - og så bag efter merger min result ind i min entity.
Avatar billede arne_v Ekspert
22. februar 2013 - 21:32 #5
Jeg er faktisk ikke specielt god til JPA.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester