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
[code]
@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.....
}
[/code]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
[code]
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();
}
.......
}
[/code]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 [
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