Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
FieldGroup con clases (entity) anidadas
Hola a todos, estoy empezando a utilizar Vaadin, el problema que les comparto es que al tratar de usar el objeto FieldGroup con una entidad anidadas obtengo:
com.vaadin.data.fieldgroup.FieldGroup$CommitException: Commit failed
at com.vaadin.data.fieldgroup.FieldGroup.commit(FieldGroup.java:492)
at com.rfrg.vaadin.example.vaadinappexample.sample.viewusuarios.UsuarioEditor.buttonClick(UsuarioEditor.java:169)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1003)
at com.vaadin.ui.Button.fireClick(Button.java:377)
at com.vaadin.ui.Button$1.click(Button.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:408)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1667)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:172)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.vaadin.data.Buffered$SourceException
at com.vaadin.ui.AbstractField.commit(AbstractField.java:257)
at com.vaadin.data.fieldgroup.FieldGroup.commitFields(FieldGroup.java:509)
at com.vaadin.data.fieldgroup.FieldGroup.commit(FieldGroup.java:481)
... 47 more
Caused by: com.vaadin.data.util.MethodProperty$MethodException
at com.vaadin.data.util.NestedMethodProperty.invokeSetMethod(NestedMethodProperty.java:251)
at com.vaadin.data.util.NestedMethodProperty.setValue(NestedMethodProperty.java:231)
at com.vaadin.data.util.TransactionalPropertyWrapper.setValue(TransactionalPropertyWrapper.java:94)
at com.vaadin.ui.AbstractField.commit(AbstractField.java:253)
... 49 more
Caused by: java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.vaadin.data.util.NestedMethodProperty.invokeSetMethod(NestedMethodProperty.java:247)
... 52 more
les muestro el codigo de mi vista y formulario, asi como las entidades a las que quiero realizar el "bind" desde el formulario:
Entity User
@Entity
@Table(name="USERS")
@XmlRootElement
@NamedQueries({
@NamedQuery(name="User.findAll", query="SELECT u FROM User u"),
@NamedQuery(name = "User.findByUsuarioAndPassword", query = "SELECT l FROM User l WHERE l.id.username = :username and l.id.pass = :pass")
})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private UserPK id;
@Temporal(TemporalType.DATE)
@Column(name="CREATION_DATE")
private Date creationDate;
private String email;
private String loggin;
@Temporal(TemporalType.DATE)
@Column(name="MODIFICATION_DATE")
private Date modificationDate;
private String perfil;
public User() {
}
//setters and getters.....
}
Entity UserPK
@Embeddable
public class UserPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
private String firtsname;
private String lastname;
private String username;
private String pass;
public UserPK() {
}
//setters and getters.....
}
Vista desde mando a llamar un modal o Window
public class UsuarioView extends VerticalLayout implements View{
private static final long serialVersionUID = -8235808140209855392L;
public static final String VIEW_NAME = "REGISTRO DE USUARIOS";
private Table usuariosTable;
private TextField searchField;
private Button newButton;
private Button deleteButton;
private Button editButton;
private JPAContainer<User> usuarios;
private String textFilter;
public UsuarioView() {
usuarios = JPAContainerFactory.make(User.class,
JpaUtil.PERSISTENCE_UNIT);
usuarios.addNestedContainerProperty("id.username");
usuarios.addNestedContainerProperty("id.lastname");
usuarios.addNestedContainerProperty("id.firtsname");
usuarios.addNestedContainerProperty("id.pass");
buildMainArea();
}
private void buildMainArea(){
//CONSTRUCCION TABLA
usuariosTable = new Table(null, usuarios);
usuariosTable.setSizeFull();
usuariosTable.setSelectable(true);
usuariosTable.setImmediate(true);
usuariosTable.setImmediate(true);
usuariosTable.setVisibleColumns(new Object[] { "id.username", "id.lastname", "id.firtsname", "loggin",
"perfil", "email", "creationDate", "modificationDate"});
usuariosTable.setColumnHeaders(new String[] { "USERNAME", "NOMBRES", "APELLIDOS", "ESTATUS",
"PERFIL", "CORREO", "FECHA ALTA", "FECHA MODIFICACION"});
// AGREGAMOS CONVERTIDORES A LAS COLUMNAS
usuariosTable.setConverter("loggin", new IntegerToStringPerfilConverter());
usuariosTable.setConverter("perfil", new IntegerToStringPerfilConverter());
// AGREGAMOS EVENTO PARA QUE SE HABILITEN LOS BOTONES DE BORRADO Y EDICION
usuariosTable.addValueChangeListener(new Property.ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
setModificationsEnabled(event.getProperty().getValue() != null);
}
private void setModificationsEnabled(boolean b) {
deleteButton.setEnabled(b);
editButton.setEnabled(b);
}
});
//CONSTRUCCION TOOLBAR
HorizontalLayout toolbar = new HorizontalLayout();
newButton = new Button("Nuevo");
// CREAMOS LISTENER PARA EL BOTON NUEVO USUARIO
newButton.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
final BeanItem<User> newUsuarioItem = new BeanItem<User>(new User());
newUsuarioItem.addNestedProperty("id.username");
newUsuarioItem.addNestedProperty("id.firtsname");
newUsuarioItem.addNestedProperty("id.lastname");
newUsuarioItem.addNestedProperty("id.pass");
UsuarioEditor usuarioEditor = new UsuarioEditor(newUsuarioItem);
final String hola = usuarioEditor.getHola();
usuarioEditor.addCloseListener(new Window.CloseListener(){
@Override
public void windowClose(CloseEvent e) {
Notification.show("Value changed:",
String.valueOf(((ValueChangeEvent) e).getProperty().getValue()),
Type.TRAY_NOTIFICATION);
}
});
.......
}
y el modal donde construyo la forma y utilizo FieldGroup
public class UsuarioEditor extends Window implements Button.ClickListener {
private static final long serialVersionUID = 19967873878950719L;
private final Item usuarioItem;
private FormLayout editorForm;
private final BeanFieldGroup<User> binder;
private Button saveButton;
private Button cancelButton;
private TextField nombresTxt;
private TextField apellidosTxt;
private TextField usernameTxt;
private TextField passwordTxt;
private TextField emailTxt;
private OptionGroup activoOptionGrp;
private OptionGroup perfilOptionGrp;
private DateField creationDate;
private DateField modificationDate;
public UsuarioEditor(Item usuarioItem) {
super("Usuario Editor");
center();
setModal(true);
this.usuarioItem = usuarioItem;
editorForm = new FormLayout();
nombresTxt = new TextField("NOMBRES:");
apellidosTxt = new TextField("APELLIDOS:", "");
usernameTxt = new TextField("USERNAME:", "");
passwordTxt = new TextField("PASSWORD:", "");
emailTxt = new TextField("EMAIL:", "");
activoOptionGrp = new OptionGroup("ACTIVO:");
perfilOptionGrp = new OptionGroup("PERFIL:");
creationDate = new DateField("FECHA CREACION:", new Date());
modificationDate = new DateField("FECHA MODIFICACION:", new Date());
activoOptionGrp.addItem("0");
activoOptionGrp.setItemCaption("0", "INACTIVO");
activoOptionGrp.addItem("1");
activoOptionGrp.setItemCaption("1", "ACTIVO");
perfilOptionGrp.addItem("0");
perfilOptionGrp.setItemCaption("0", "ADMINISTRADOR");
perfilOptionGrp.addItem("1");
perfilOptionGrp.setItemCaption("1", "USUARIO");
editorForm.addComponent(nombresTxt);
editorForm.addComponent(apellidosTxt);
editorForm.addComponent(usernameTxt);
editorForm.addComponent(passwordTxt);
editorForm.addComponent(emailTxt);
editorForm.addComponent(activoOptionGrp);
editorForm.addComponent(perfilOptionGrp);
editorForm.addComponent(creationDate);
editorForm.addComponent(modificationDate);
saveButton = new Button("Save", this);
cancelButton = new Button("Cancel", this);
HorizontalLayout horizontalLayout = new HorizontalLayout();
horizontalLayout.addComponent(saveButton);
horizontalLayout.addComponent(cancelButton);
editorForm.addComponent(horizontalLayout);
binder = new BeanFieldGroup<User>(User.class);
binder.setItemDataSource(new User());
binder.bind(nombresTxt, "id.firtsname");
binder.bind(apellidosTxt, "id.lastname");
binder.bind(usernameTxt, "id.username");
binder.bind(passwordTxt, "id.pass");
binder.bind(emailTxt, "email");
binder.bind(activoOptionGrp, "loggin");
binder.bind(perfilOptionGrp, "perfil");
binder.bind(creationDate, "creationDate");
binder.bind(modificationDate, "modificationDate");
for (final Object propertyId : binder.getUnboundPropertyIds()) {
System.out.println("propertyId.-"+propertyId);
}
setSizeUndefined();
setContent(editorForm);
}
@Override
public void buttonClick(ClickEvent event) {
if (event.getButton() == saveButton) {
try {
System.out.println("saveButton");
binder.commit(); <---HERE NPE
BeanItem ok = ((BeanItem)binder.getItemDataSource());
System.out.println("bean.-"+ok.getBean().toString());
} catch (CommitException e) {
e.printStackTrace();
}
} else if (event.getButton() == cancelButton) {
binder.discard();
}
close();
}
.......
}
Otra cosa, es que cuando creo el formulario me aparecen los campos TextField con la palabra "null"
por ultimo, si comento las lineas :
binder.bind(nombresTxt, "id.firtsname");
binder.bind(apellidosTxt, "id.lastname");
binder.bind(usernameTxt, "id.username");
binder.bind(passwordTxt, "id.pass");
en la clase UsuarioEditor funciona, pero de la siguiente manera:
bean.-User [[i]id=null, creationDate=Thu Feb 11 00:00:00 CST 2016, email=correo, loggin=0, modificationDate=Thu Feb 11 00:00:00 CST 2016, perfil=1]
la versión que ocupo de vaadin es
<vaadin.version>7.6.1</vaadin.version>
Gracias de antemano.
Saludos