PersonEditDetails refreshes Person from database at error. Changes are discarted.

master
Markus Kreth 6 years ago
parent 42cba2ce69
commit c5e6f01a55
  1. 4
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/business/PersonBusiness.java
  2. 7
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/AbstractDaoImpl.java
  3. 1
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/IDao.java
  4. 9
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Contact.java
  5. 51
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java
  6. 7
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/security/SecurityVerifierImpl.java
  7. 11
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/AbstractDataGrid.java
  8. 3
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/ContactGrid.java
  9. 41
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonEditDetails.java
  10. 8
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonFilter.java
  11. 10
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/PersonGroupValidator.java
  12. 16
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/PersonEditView.java
  13. 20
      src/main/resources/log4j2.xml

@ -57,4 +57,8 @@ public class PersonBusiness {
return dao.findLoginUser(username, password);
}
public Person getById(int id) {
return dao.get(id);
}
}

@ -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,7 +35,6 @@ public abstract class AbstractDaoImpl<T extends EntityAccessor> implements IDao<
Date now = new Date();
obj.setChanged(now);
try {
if (entityManager.contains(obj) || obj.hasValidId()) {
entityManager.merge(obj);
}
@ -45,11 +43,6 @@ public abstract class AbstractDaoImpl<T extends EntityAccessor> implements IDao<
entityManager.persist(obj);
}
}
catch (DataAccessException e) {
entityManager.refresh(obj);
throw e;
}
}
@Override
public T get(Object primaryKey) {

@ -10,4 +10,5 @@ public interface IDao<T> extends Serializable {
List<T> listAll();
T get(Object primaryKey);
}

@ -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;

@ -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<Adress> 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<Attendance> 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<Contact> 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<GroupDef> 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<Adress> getAdresses() {
if (adresses == null) {
return Collections.emptyList();
}
return adresses;
}
@ -181,6 +195,9 @@ public class Person extends BaseEntity implements Serializable {
}
public List<Attendance> getAttendances() {
if (attendances == null) {
return Collections.emptyList();
}
return attendances;
}
@ -189,6 +206,9 @@ public class Person extends BaseEntity implements Serializable {
}
public List<Contact> getContacts() {
if (contacts == null) {
return Collections.emptyList();
}
return contacts;
}
@ -197,6 +217,9 @@ public class Person extends BaseEntity implements Serializable {
}
public Set<GroupDef> getGroups() {
if (groups == null) {
return Collections.emptySet();
}
return groups;
}
@ -205,6 +228,9 @@ public class Person extends BaseEntity implements Serializable {
}
public List<Relative> getRelatives1() {
if (relatives1 == null) {
return Collections.emptyList();
}
return relatives1;
}
@ -213,6 +239,9 @@ public class Person extends BaseEntity implements Serializable {
}
public List<Relative> getRelatives2() {
if (relatives2 == null) {
return Collections.emptyList();
}
return relatives2;
}
@ -221,6 +250,9 @@ public class Person extends BaseEntity implements Serializable {
}
public Set<ClubEvent> 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;
}
}

@ -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,19 +28,17 @@ public class SecurityVerifierImpl implements SecurityVerifier {
if (person != null) {
for (SecurityGroups g : groups) {
for (GroupDef def : person.getGroups()) {
if (g.getValue().equalsIgnoreCase(def.getName())) {
if (person.hasGroup(g.getValue())) {
return true;
}
}
}
}
return false;
}
@Override
public boolean isLoggedin() {
return person != null && person.getGroups() != null && person.getGroups().isEmpty() == false;
return person != null && person.hasAnyGroup();
}
}

@ -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<T> extends VerticalLayout {
private final List<T> source;
private final ListDataProvider<T> dataProvider;
private final Supplier<Boolean> hasChanges;
private boolean hasChanges;
private final ListDataProvider<T> dataProvider;
private Column<T, Component> deleteButtonColumn;
@ -62,7 +63,6 @@ public abstract class AbstractDataGrid<T> extends VerticalLayout {
grid.addSelectionListener(ev -> editedListener.editObject = null);
Binder<T> binder = editor.getBinder();
editor.addSaveListener(ev -> {
hasChanges = true;
if (editedListener.editObject != null) {
for (Consumer<T> consumer : successConsumers) {
consumer.accept(ev.getBean());
@ -76,6 +76,8 @@ public abstract class AbstractDataGrid<T> 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<T> 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<T> extends VerticalLayout {
protected abstract Collection<? extends T> readValues(Person person);
public final boolean hasChanges() {
return hasChanges;
return hasChanges.get().booleanValue();
}
class EditedListener implements EditorCancelListener<T> {

@ -20,9 +20,6 @@ import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person;
public class ContactGrid extends AbstractDataGrid<Contact> {
/**
*
*/
private static final long serialVersionUID = -2573761302198992085L;
private static final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();

@ -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<Person> validate = binder.validate();
if (validate.isOk()) {
Person edited = binder.getBean();
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<ValidationResult> 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()) {

@ -68,20 +68,18 @@ public class PersonFilter implements SerializablePredicate<Person>, 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<GroupDef> groups, Set<GroupDef> selectedGroups2) {
private boolean haveCommonGroup(Person p, Set<GroupDef> selectedGroups2) {
for (GroupDef g1 : groups) {
for (GroupDef g2 : selectedGroups2) {
if (g1.getId() == g2.getId()) {
if (p.hasGroup(g2)) {
return true;
}
}
}
return false;
}

@ -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<Person> {
@ -15,11 +12,10 @@ public class PersonGroupValidator implements Validator<Person> {
@Override
public ValidationResult apply(Person value, ValueContext context) {
Set<GroupDef> 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();
}
}

@ -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<Person> 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<Person> 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<Person> 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());
}
}

@ -4,7 +4,16 @@
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<RollingFile name="MyFile" fileName="${catalina.base}/logs/vaadin_clubhelper.log" immediateFlush="false" append="true">
<RollingFile name="MyFile" fileName="E:/Markus/eclipse_workspace/logs/vaadin_clubhelper.log" immediateFlush="false" append="true">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %logger %m%n </Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy max="5" />
</RollingFile>
<RollingFile name="SqlFile" fileName="E:/Markus/eclipse_workspace/logs/logs/vaadin_clubhelper_sql.log" immediateFlush="true" append="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %logger %m%n </Pattern>
</PatternLayout>
@ -25,5 +34,14 @@
<AppenderRef ref="MyFile"/>
</Logger>
<Logger name="org.hibernate.SQL" additivity="false" level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="SqlFile"/>
</Logger>
<Logger name="org.hibernate.type.descriptor.sql" additivity="false" level="trace">
<AppenderRef ref="Console" />
<AppenderRef ref="SqlFile"/>
</Logger>
</Loggers>
</Configuration>

Loading…
Cancel
Save