Ich habe diesen speziellen Fall, der mir einige Zweifel aufkommen lässt: Meine Klasse A hat eine Eins-zu-viele-Beziehung mit B:
A 1----->* B
Was, soweit ich weiß, ihre Verwandtschaft ausmachtInstanzen gehören zu derselben Entitätsgruppe. Ich muss eine bestimmte A-Instanz und eine ihrer B abrufen, also suche ich nach A und iteriere durch die B-Liste, um das bestimmte B zu finden (immer nach Id suchend). Danach ändere ich ein Attribut von A und B und begehe meine Änderungen, indem ich A fusioniere. Hier sind meine Fragen:
- Wissend, dass ich A und B abrufen muss (weil ich beide modifizieren muss), sollte ich 2 Suchen durchführen anstatt die B Liste zu wiederholen?
- Wenn ich 2 Suchen mache, bleiben Änderungen an B bestehen, wenn ich nur A behalte.
- Werden Frage 1 und 2 in diesem Fall die gleiche Antwort haben:
A 1----->* C 1----->* B
Ergänzen Sie die Frage mit etwas Code:
@Entity
public class A
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
private int aField;
@OneToMany(cascade={CascadeType.ALL})
private List<B> bList;
//...
}
@Entity
public class B
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
private int someBField;
// no way to get A from here...
//...
}
public void someService1(Key aKey, Key bKey)
{
//...
// Here, I"m sure that bKey is of an entity son of aKey entity (I trust the client)
A a = entityManager.find(A.class, aKey);
a.setAField(a.getAField()++);
for(B b : a.getBList())
if(b.getKey().equals(bKey))
b.setSomeBField(b.getSomeBField()++);
entityManager.merge(a);
//...
}
public void someService2(Key aKey, Key bKey)
{
//...
// Here, I"m sure that bKey is of an entity son of aKey entity (I trust the client)
A a = entityManager.find(A.class, aKey);
a.setAField(a.getAField()++);
B b = entityManager.find(B.class, bKey);
b.setSomeBField(b.getSomeBField()++);
entityManager.merge(a);
//...
}
Nun, sowohl someService1 als auch someService2 machen dasselbe, wenn ich alles richtig gemacht habe. Welches ist besser?
Antworten:
1 für die Antwort № 1Wenn du die ID kennst (und du sagst, dass du nach ID suchst) dann tu einfach ein em.find
für das A und em.find
für die B. Zwei Anrufe. Leider hat die JPA API keine em.findAll
. JDO hingegen hat es pm.getObjectsById
2 für die Antwort № 2
Wenn ich richtig verstanden habe, muss man nicht durch irgendetwas hindurch iterieren, sondern stattdessen das filter()
auf irgendwelchen Query
du magst. Beispiele (Python):
query.filter("height >", 42).filter("city = ", "Seattle")
query.filter("user = ", users.get_current_user())
Wenn Sie Java verwenden, werden Sie es verwenden addFilter
auf Ihre Anfragen (Mehr Info).