簡単な答えは、これはできないということです。
しかし、あなたの問題に適した解決策は次のとおりです。
エンティティ A では、エンティティ B との関係をリストとして定義しています (または、同じ B を複数回含めることができないように、セットとしてさらに優れています)。
@OneToMany(mappedBy="a")
private Set<B> bs;
プレーンなリストを公開したくないので、 の getter と setter を省略しas
ます。
次に、オンザフライでマップを構築するマップのゲッターを定義できます。
// a transient field to cache the map
private transient Map<String, B> bsMappedByCName;
public Map<String, B> getBsMappedByCName() {
if(bsMappedByCName == null) {
bsMappedByCName = new HashMap<String, B>();
for(B b : bs) {
mapB(b);
}
}
// return as unmodifiable map so that it is immutable for clients
return Collections.unmodifiableMap(bsMappedByCName);
}
private void mapB(B b) {
// we assume here that field c in class B and likely also field name in class C are not nullable. Further more both of this fields sould be immutable (i.e. have no setter).
if(bsMappedByCName.put(b.getC().getName(), b) != null) {
// multiple bs with same CName, this is an inconsistency you may handle
}
}
対処する最後の問題は、新しい B を A に追加する方法、または削除する方法です。マップを変更不可として返す戦略では、クラス A にいくつかの追加メソッドと削除メソッドを提供する必要があります。
public void addB(B b) {
bs.add(b);
mapB(b);
}
public void removeB(B b) {
bs.remove(b);
bsMappedByCName.remove(b.getC().getName());
}
他のオプションは、( apache の ObservaleCollection にreturn Collections.unmodifiableMap(...)
触発された)に置き換えることです:
return new Map<String, B>() {
// implement all methods that add or remove elements in map with something like this
public B put(String name, B b) {
// check consistency
if(!b.getC().getName().equals(name)) {
// this sould be handled as an error
}
B oldB = get(name);
mapB(b);
return oldB;
}
// implement all accessor methods like this
public B get(String name) {
return bsMappedByCName.get(name);
}
// and so on...
};