From c5e6f01a55767eb55b4fdefe178ea0b84979c408 Mon Sep 17 00:00:00 2001 From: Markus Kreth Date: Sat, 17 Aug 2019 18:47:54 +0200 Subject: [PATCH] PersonEditDetails refreshes Person from database at error. Changes are discarted. --- .../business/PersonBusiness.java | 4 ++ .../vaadinclubhelper/dao/AbstractDaoImpl.java | 17 ++----- .../clubhelper/vaadinclubhelper/dao/IDao.java | 1 + .../vaadinclubhelper/data/Contact.java | 9 ---- .../vaadinclubhelper/data/Person.java | 51 ++++++++++++++++++- .../security/SecurityVerifierImpl.java | 9 ++-- .../ui/components/AbstractDataGrid.java | 11 ++-- .../ui/components/ContactGrid.java | 3 -- .../ui/components/PersonEditDetails.java | 43 +++++++++++----- .../ui/components/PersonFilter.java | 12 ++--- .../ui/components/PersonGroupValidator.java | 10 ++-- .../ui/navigation/PersonEditView.java | 16 ++++-- src/main/resources/log4j2.xml | 20 +++++++- 13 files changed, 138 insertions(+), 68 deletions(-) diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/business/PersonBusiness.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/business/PersonBusiness.java index 39b5490..5d3a316 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/business/PersonBusiness.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/business/PersonBusiness.java @@ -57,4 +57,8 @@ public class PersonBusiness { return dao.findLoginUser(username, password); } + public Person getById(int id) { + return dao.get(id); + } + } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/AbstractDaoImpl.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/AbstractDaoImpl.java index 534f33e..fd8c8e9 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/AbstractDaoImpl.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/AbstractDaoImpl.java @@ -9,7 +9,6 @@ import javax.persistence.TypedQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; import org.springframework.transaction.annotation.Transactional; import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.EntityAccessor; @@ -36,18 +35,12 @@ public abstract class AbstractDaoImpl implements IDao< Date now = new Date(); obj.setChanged(now); - try { - if (entityManager.contains(obj) || obj.hasValidId()) { - entityManager.merge(obj); - } - else { - obj.setCreated(now); - entityManager.persist(obj); - } + if (entityManager.contains(obj) || obj.hasValidId()) { + entityManager.merge(obj); } - catch (DataAccessException e) { - entityManager.refresh(obj); - throw e; + else { + obj.setCreated(now); + entityManager.persist(obj); } } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/IDao.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/IDao.java index 9a2a1c7..cf82d6f 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/IDao.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/IDao.java @@ -10,4 +10,5 @@ public interface IDao extends Serializable { List listAll(); T get(Object primaryKey); + } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Contact.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Contact.java index b9c9ef9..73405cb 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Contact.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Contact.java @@ -57,7 +57,6 @@ public class Contact extends BaseEntity implements Serializable { public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + ((person == null) ? 0 : person.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); return result; @@ -75,14 +74,6 @@ public class Contact extends BaseEntity implements Serializable { return false; } Contact other = (Contact) obj; - if (person == null) { - if (other.person != null) { - return false; - } - } - else if (!person.equals(other.person)) { - return false; - } if (type == null) { if (other.type != null) { return false; diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java index 80fd395..f35aa72 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -58,21 +59,25 @@ public class Person extends BaseEntity implements Serializable { // bi-directional many-to-one association to Adress @OneToMany(mappedBy = "person", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, + CascadeType.REMOVE, CascadeType.REFRESH }) private List adresses; // bi-directional many-to-one association to Attendance @OneToMany(mappedBy = "person", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, + CascadeType.REMOVE, CascadeType.REFRESH }) private List attendances; // bi-directional many-to-one association to Contact @OneToMany(mappedBy = "person", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, + CascadeType.REMOVE, CascadeType.REFRESH }) private List contacts; // bi-directional many-to-many association to Persongroup - @ManyToMany(targetEntity = GroupDef.class, fetch = FetchType.EAGER, cascade = { CascadeType.REFRESH }) + @ManyToMany(targetEntity = GroupDef.class, fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, + CascadeType.REFRESH }) @JoinTable(name = "persongroup", joinColumns = { @JoinColumn(name = "person_id") }, inverseJoinColumns = { @JoinColumn(name = "group_id") }) private Set groups; @@ -113,6 +118,12 @@ public class Person extends BaseEntity implements Serializable { this.groups.add(group); } + public void remove(GroupDef g) { + if (this.groups != null) { + this.groups.remove(g); + } + } + public void add(ClubEvent ev) { if (this.events == null) { this.events = new HashSet<>(); @@ -173,6 +184,9 @@ public class Person extends BaseEntity implements Serializable { } public List getAdresses() { + if (adresses == null) { + return Collections.emptyList(); + } return adresses; } @@ -181,6 +195,9 @@ public class Person extends BaseEntity implements Serializable { } public List getAttendances() { + if (attendances == null) { + return Collections.emptyList(); + } return attendances; } @@ -189,6 +206,9 @@ public class Person extends BaseEntity implements Serializable { } public List getContacts() { + if (contacts == null) { + return Collections.emptyList(); + } return contacts; } @@ -197,6 +217,9 @@ public class Person extends BaseEntity implements Serializable { } public Set getGroups() { + if (groups == null) { + return Collections.emptySet(); + } return groups; } @@ -205,6 +228,9 @@ public class Person extends BaseEntity implements Serializable { } public List getRelatives1() { + if (relatives1 == null) { + return Collections.emptyList(); + } return relatives1; } @@ -213,6 +239,9 @@ public class Person extends BaseEntity implements Serializable { } public List getRelatives2() { + if (relatives2 == null) { + return Collections.emptyList(); + } return relatives2; } @@ -221,6 +250,9 @@ public class Person extends BaseEntity implements Serializable { } public Set getEvents() { + if (events == null) { + return Collections.emptySet(); + } return events; } @@ -496,4 +528,21 @@ public class Person extends BaseEntity implements Serializable { return "Person [id=" + getId() + ", prename=" + prename + ", surname=" + surname + "]"; } + public boolean hasGroup(GroupDef g) { + return groups != null && groups.contains(g); + } + + public boolean hasAnyGroup() { + return groups != null && !groups.isEmpty(); + } + + public boolean hasGroup(String value) { + for (GroupDef g : groups) { + if (g.getName().equalsIgnoreCase(value)) { + return true; + } + } + return false; + } + } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/security/SecurityVerifierImpl.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/security/SecurityVerifierImpl.java index 8a56c66..f6d153c 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/security/SecurityVerifierImpl.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/security/SecurityVerifierImpl.java @@ -4,7 +4,6 @@ import org.springframework.stereotype.Service; import com.vaadin.server.VaadinSession; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.GroupDef; import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; @Service @@ -29,10 +28,8 @@ public class SecurityVerifierImpl implements SecurityVerifier { if (person != null) { for (SecurityGroups g : groups) { - for (GroupDef def : person.getGroups()) { - if (g.getValue().equalsIgnoreCase(def.getName())) { - return true; - } + if (person.hasGroup(g.getValue())) { + return true; } } } @@ -41,7 +38,7 @@ public class SecurityVerifierImpl implements SecurityVerifier { @Override public boolean isLoggedin() { - return person != null && person.getGroups() != null && person.getGroups().isEmpty() == false; + return person != null && person.hasAnyGroup(); } } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/AbstractDataGrid.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/AbstractDataGrid.java index 5aeb7a2..8f5f703 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/AbstractDataGrid.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/AbstractDataGrid.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.Consumer; +import java.util.function.Supplier; import com.vaadin.data.Binder; import com.vaadin.data.ValidationResult; @@ -33,9 +34,9 @@ public abstract class AbstractDataGrid extends VerticalLayout { private final List source; - private final ListDataProvider dataProvider; + private final Supplier hasChanges; - private boolean hasChanges; + private final ListDataProvider dataProvider; private Column deleteButtonColumn; @@ -62,7 +63,6 @@ public abstract class AbstractDataGrid extends VerticalLayout { grid.addSelectionListener(ev -> editedListener.editObject = null); Binder binder = editor.getBinder(); editor.addSaveListener(ev -> { - hasChanges = true; if (editedListener.editObject != null) { for (Consumer consumer : successConsumers) { consumer.accept(ev.getBean()); @@ -76,6 +76,8 @@ public abstract class AbstractDataGrid extends VerticalLayout { binder.withValidator((obj, context) -> validate(obj, context)); + this.hasChanges = () -> binder.hasChanges(); + deleteButtonColumn = grid.addComponentColumn(c -> { Button deleteButton = new Button(VaadinIcons.TRASH); deleteButton.addClickListener(ev -> deleteConsumer.accept(c)); @@ -124,7 +126,6 @@ public abstract class AbstractDataGrid extends VerticalLayout { } public final void setPerson(Person person) { - hasChanges = false; source.clear(); if (person != null) { source.addAll(readValues(person)); @@ -135,7 +136,7 @@ public abstract class AbstractDataGrid extends VerticalLayout { protected abstract Collection readValues(Person person); public final boolean hasChanges() { - return hasChanges; + return hasChanges.get().booleanValue(); } class EditedListener implements EditorCancelListener { diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/ContactGrid.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/ContactGrid.java index fa75e8b..072423e 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/ContactGrid.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/ContactGrid.java @@ -20,9 +20,6 @@ import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; public class ContactGrid extends AbstractDataGrid { - /** - * - */ private static final long serialVersionUID = -2573761302198992085L; private static final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonEditDetails.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonEditDetails.java index 99d45c4..1f0783f 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonEditDetails.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonEditDetails.java @@ -5,6 +5,7 @@ import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.dao.DataAccessException; import org.vaadin.teemu.switchui.Switch; import com.vaadin.data.Binder; @@ -86,7 +87,7 @@ public class PersonEditDetails extends HorizontalLayout { return startpass.getStartpassNr(); }, (p, value) -> p.setStartpass(value)); - binder.withValidator(p -> (p.getGroups() != null && p.getGroups().isEmpty() == false), + binder.withValidator(p -> (p.hasAnyGroup()), "Mind. eine Gruppe muss gewählt sein!"); Button close = new Button("Schließen"); @@ -99,16 +100,22 @@ public class PersonEditDetails extends HorizontalLayout { okButton = new Button("Speichern"); okButton.addClickListener(ev -> { + okButton.setComponentError(null); BinderValidationStatus validate = binder.validate(); if (validate.isOk()) { Person edited = binder.getBean(); - dao.save(edited); + try { + dao.save(edited); + } + catch (DataAccessException e) { + edited = dao.getById(edited.getId()); + updateBean(edited); + throw e; + } if (personChangeHandler != null) { personChangeHandler.accept(binder.getBean()); } - contactLayout.setPerson(edited); - relationshipLayout.setPerson(edited); - adressLayout.setPerson(edited); + updateBean(edited); } else { List errors = validate.getBeanValidationErrors(); @@ -177,16 +184,15 @@ public class PersonEditDetails extends HorizontalLayout { static boolean containsGroup(Person p, GroupDef g) { return p != null - && p.getGroups() != null - && p.getGroups().contains(g); + && p.hasGroup(g); } static void changeGroupContent(Person p, GroupDef g, boolean schouldBeContained) { if (schouldBeContained) { - p.getGroups().add(g); + p.add(g); } else { - p.getGroups().remove(g); + p.remove(g); } } @@ -226,10 +232,10 @@ public class PersonEditDetails extends HorizontalLayout { public void setBean(Person person) { closeWithoutSave(); - binder.setBean(person); - contactLayout.setPerson(person); - relationshipLayout.setPerson(person); - adressLayout.setPerson(person); + + okButton.setComponentError(null); + + updateBean(person); if (person != null) { iterator().forEachRemaining(comp -> comp.setEnabled(true)); @@ -242,6 +248,17 @@ public class PersonEditDetails extends HorizontalLayout { } } + public Person currentBean() { + return binder.getBean(); + } + + private void updateBean(Person person) { + contactLayout.setPerson(person); + relationshipLayout.setPerson(person); + adressLayout.setPerson(person); + binder.setBean(person); + } + public void closeWithoutSave() { if (hasChanges()) { diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonFilter.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonFilter.java index 2a226a4..ead1108 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonFilter.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonFilter.java @@ -68,18 +68,16 @@ public class PersonFilter implements SerializablePredicate, DataProvider private boolean personInGroup(Person t) { if (selectedGroups != null) { - return t.getGroups() != null && haveCommonGroup(t.getGroups(), selectedGroups); + return t.hasAnyGroup() == false && haveCommonGroup(t, selectedGroups); } return true; } - private boolean haveCommonGroup(Set groups, Set selectedGroups2) { + private boolean haveCommonGroup(Person p, Set selectedGroups2) { - for (GroupDef g1 : groups) { - for (GroupDef g2 : selectedGroups2) { - if (g1.getId() == g2.getId()) { - return true; - } + for (GroupDef g2 : selectedGroups2) { + if (p.hasGroup(g2)) { + return true; } } return false; diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonGroupValidator.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonGroupValidator.java index 6731a37..3afeb84 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonGroupValidator.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonGroupValidator.java @@ -1,12 +1,9 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components; -import java.util.Set; - import com.vaadin.data.ValidationResult; import com.vaadin.data.Validator; import com.vaadin.data.ValueContext; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.GroupDef; import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; public class PersonGroupValidator implements Validator { @@ -15,11 +12,10 @@ public class PersonGroupValidator implements Validator { @Override public ValidationResult apply(Person value, ValueContext context) { - Set gr = value.getGroups(); - if (gr != null && gr.isEmpty() == false) { - return ValidationResult.ok(); + if (value.hasAnyGroup()) { + return ValidationResult.error("Es müssen Gruppen gesetzt sein!"); } - return ValidationResult.error("Es müssen Gruppen gesetzt sein!"); + return ValidationResult.ok(); } } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/PersonEditView.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/PersonEditView.java index d705bf1..2b88c7f 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/PersonEditView.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/PersonEditView.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.vaadin.event.selection.SelectionEvent; import com.vaadin.navigator.Navigator; import com.vaadin.navigator.View; @@ -27,6 +30,8 @@ public class PersonEditView extends VerticalLayout implements View { private static final long serialVersionUID = 1770993670570422036L; + private static final Logger LOG = LoggerFactory.getLogger(PersonEditView.class); + private ClubhelperMenuBar menuBar; private PersonGrid personGrid; @@ -64,9 +69,6 @@ public class PersonEditView extends VerticalLayout implements View { addPerson.addClickListener(ev -> addPerson()); addComponent(addPerson); -// Button backButton = new Button("Zurück"); -// backButton.addClickListener(ev -> navigator.navigateTo(ClubhelperViews.MainView.name())); -// addComponent(backButton); } public HorizontalLayout createHorizontalLayout() { @@ -97,6 +99,7 @@ public class PersonEditView extends VerticalLayout implements View { void selectedPerson(SelectionEvent p) { if (personDetails.hasChanges()) { + LOG.info("Current Person has changed - selection suspended for question"); VerticalLayout content = new VerticalLayout(); Window dlg = new Window("Änderungen verwerfen?", content); dlg.setClosable(false); @@ -108,6 +111,7 @@ public class PersonEditView extends VerticalLayout implements View { content.addComponent(message); HorizontalLayout buttons = new HorizontalLayout(); Button ok = new Button("Ja", ev -> { + LOG.warn("Discating changes in " + personDetails.currentBean()); dlg.setVisible(false); PersonEditView.this.getUI().removeWindow(dlg); Optional firstSelectedItem = p.getFirstSelectedItem(); @@ -115,6 +119,7 @@ public class PersonEditView extends VerticalLayout implements View { }); Button cancel = new Button("Nein", ev -> { dlg.setVisible(false); + LOG.info("Canceling new Person selection"); PersonEditView.this.getUI().removeWindow(dlg); }); buttons.addComponents(ok, cancel); @@ -124,7 +129,9 @@ public class PersonEditView extends VerticalLayout implements View { } else { Optional firstSelectedItem = p.getFirstSelectedItem(); - personDetails.setBean(firstSelectedItem.orElse(null)); + Person selection = firstSelectedItem.orElse(null); + personDetails.setBean(selection); + LOG.info("Changed selection to " + selection); } } @@ -132,6 +139,7 @@ public class PersonEditView extends VerticalLayout implements View { public void enter(ViewChangeEvent event) { this.navigator = event.getNavigator(); menuBar.applyState(menuStateFactory.currentState()); + LOG.debug("opened {}", getClass().getName()); } } diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 6056ebc..eef92f0 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -4,7 +4,16 @@ - + + + %d{yyyy-MM-dd HH:mm:ss} %-5p %logger %m%n + + + + + + + %d{yyyy-MM-dd HH:mm:ss} %-5p %logger %m%n @@ -25,5 +34,14 @@ + + + + + + + + +