selectManyCheckbox with extra InputText: A better way to do this?
bolke May 26, 2008 9:10 PMHello,
I have a relationship between two entities which is essentially a manytomany relation ship if not for the extra data the relationship can provide. Therefore I have created a connector class.
in Chemical.java @OneToMany(mappedBy="chemical", cascade=CascadeType.ALL) private List<ChemicalNoteConnector> notes; in ChemicalNoteConnector.java @ManyToOne private Chemical chemical; @ManyToOne private ChemicalNote chemicalNote; in ChemicalNote.java @OneToMany(mappedBy="chemicalNote", cascade=CascadeType.ALL) private List<ChemicalNoteConnector> chemicals;
A normal ManyToMany relation ship is quite easily solved using a selectManyCheckbox for the frontend. However it does not allow for the extra data. To solve this I added
@In(required=false) @Out private List<NoteSelectItem> notes;
which uses a class derived from SelectItem to contain the relationship. This uses a lot of plumbing code to make it work and just does not seam very efficient to me. Eg:
@SuppressWarnings("unchecked")
public void findNotes() {
if (chemical == null)
return;
List<ChemicalNoteConnector> connectedNotes;
if (entityManager.contains(chemical)) {
connectedNotes =
entityManager.createQuery("from ChemicalNoteConnector cnn where cnn.chemical = :chemical")
.setParameter("chemical", chemical)
.getResultList();
} else {
connectedNotes = new ArrayList<ChemicalNoteConnector>();
}
List<ChemicalNote> notesList = entityManager.createQuery("from ChemicalNote c order by c.number asc").getResultList();
List<NoteSelectItem> items = new ArrayList<NoteSelectItem>();
for (ChemicalNote n : notesList) {
NoteSelectItem item = new NoteSelectItem();
item.setLabel(Integer.toString(n.getNumber()));
item.setValue(n);
for (ChemicalNoteConnector cnn : connectedNotes) {
if (cnn.getChemicalNote().getNumber() == n.getNumber()) {
item.setSelected(true);
item.setExtra(cnn.getExtra());
break;
}
}
items.add(item);
}
notes = items;
}
private void setNotes() {
log.info("chemicalManager.setNotes called");
if (entityManager.contains(chemical)) {
for (ChemicalNoteConnector nc : chemical.getNotes()) {
nc.getChemicalNote().getChemicals().remove(nc);
entityManager.remove(nc);
}
chemical.setNotes(null);
entityManager.flush();
}
List<ChemicalNoteConnector> connectors = new ArrayList<ChemicalNoteConnector>();
for (NoteSelectItem item : notes) {
if (!item.isSelected())
continue;
log.info("Adding connector: " + item.getLabel() + " extra: " + item.getExtra());
ChemicalNoteConnector connector = new ChemicalNoteConnector();
connector.setChemical(chemical);
connector.setChemicalNote((ChemicalNote) item.getValue());
// Empty inputtexts are not null
if (item.getExtra() != null || !item.getExtra().equals(""))
connector.setExtra(item.getExtra());
connectors.add(connector);
}
chemical.setNotes(connectors);
}
Well it works. But I was thinking there should be an easier way as I think the extra data part if a quite common requirement. Does someone have an idea and is willing to share it?
Thanks!