Короткий ответ: ты не можешь этого сделать.
Но вот решение, которое может подойти для вашей проблемы:
В объекте A все еще определено отношение к объекту B как List (или даже лучше как Set, так что один и тот же 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());
}
Другой вариант - заменить return Collections.unmodifiableMap(...)
на (вдохновленный ObservaleCollection от apache ):
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...
};