Vaadin DateField将空值保存到数据库 [英] Vaadin DateField saves null value to database

查看:85
本文介绍了Vaadin DateField将空值保存到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用VAADIN 8并遇到问题.我已经在FormLayout上绑定了所有字段,并希望将这些字段中的值保存到db中.所有字段均填充值.问题的实质是当对象保存到数据库时,DateField值将发送为空

I'm using VAADIN 8 and struggling with a problem. I've bind all fields on FormLayout and want to save values ​​from these fields in a db. All fields are filled with values. The essence of the problem is that the DateField value is sent as null when the object is saved to the database

问题是为什么DateFiled具有空值,以及如何解决该问题?

The question is why DateFiled has null value and how to win the problem?

VAADIN v.8.6.2

VAADIN v.8.6.2

实体(简体):

@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "Orders")
public class Order{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "OrderID", nullable = false)
    private Long orderID;

    @Column(name = "Description", nullable = false, length = 1000)
    private String description;

    @Column(name = "CreationDate", nullable = false)
    private Date creationDate;

public Long getOrderID() { return orderID; }

public String getDescription() { return description; }

public void setDescription(String description) { this.description = description; }

public Date getCreationDate() { return creationDate; }

public void setCreationDate(Date creationDate) { this.creationDate = creationDate; }

}

OrderService(简体):

OrderService(simplified):

public class OrderService {

    private static OrderDao orderService;

    public OrderService() {
        orderService = new OrderDao();
    }

    public void persist(Order entity) {
        orderService.openCurrentSessionwithTransaction();
        orderService.persist(entity);
        orderService.closeCurrentSessionwithTransaction();
    }
}

绑定(简化):

Binder<Order> binder = new Binder<>(Order.class);
FormLayout formLayout = new FormLayout();
TextField description = new TextField("Description");
DateField creationDate = new DateField("Creation Date");

private Button save = new Button("Save");
private Button cancel = new Button("Cancel");

HorizontalLayout actions = new HorizontalLayout();
actions.addComponents(save, cancel);

formLayout.addComponents(clientId, description, creationDate, actions);

creationDate.setDateFormat("yyyy-MM-dd HH:mm:ss");

binder.forField(this.clientId)
        .bind(Order::getClientID, Order::setClientID);
binder.forField(this.description)
        .bind(Order::getDescription, Order::setDescription);
binder.forField(this.creationDate)
        .withConverter(new SqlDateToLocalDateConverter())
        .bind(Order::getCreationDate, Order::setCreationDate); //the likely problem

binder.bindInstanceFields(this);

binder.setBean(order);

save.addClickListener(e -> save());
cancel.addClickListener(e -> close());

转换器类别:

import com.vaadin.data.Converter;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;

import java.sql.Date;
import java.time.LocalDate;

public class SqlDateToLocalDateConverter implements Converter<LocalDate, Date> {

    @Override
    public Result<java.sql.Date> convertToModel(LocalDate value, ValueContext context) {
        if (value == null) {
            return Result.ok(null);
        }
        return Result.ok( java.sql.Date.valueOf(value) );
    }

    @Override
    public LocalDate convertToPresentation(java.sql.Date value, ValueContext context) {
        if (value == null) {
            return LocalDate.now();
        }
        return value.toLocalDate();
    }
}

调试模式指示creationDate字段为null:

debug mode indicates that the creationDate field is null:

stacktrace:

stacktrace:

org.hibernate.PropertyValueException: not-null property references a null or transient value : com.haulmont.testtask.model.Order.creationDate
        at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:108)
        at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:56)
        at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
        at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)
        at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)
        at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)
        at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
        at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:359)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:131)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
        at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
        at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
        at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:709)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:701)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:696)
        at com.haulmont.testtask.dao.OrderDao.persist(OrderDao.java:67)
        at com.haulmont.testtask.service.OrderService.persist(OrderService.java:18)
        at com.haulmont.testtask.ui.AddOrderModalView.save(AddOrderModalView.java:187)
        at com.haulmont.testtask.ui.AddOrderModalView.lambda$new$61446b05$1(AddOrderModalView.java:111)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:499)
        at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:273)
        at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:237)
        at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1014)
        at com.vaadin.ui.Button.fireClick(Button.java:384)
        at com.vaadin.ui.Button$1.click(Button.java:57)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:155)
        at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:116)
        at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:445)
        at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:410)
        at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274)
        at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
        at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
        at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1601)
        at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:445)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689)
        at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
        at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
        at org.eclipse.jetty.server.Server.handle(Server.java:524)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
        at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
        at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
        at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
        at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
        at java.lang.Thread.run(Thread.java:748)

推荐答案

一切正常,除了自定义Converter类中的一个小细节之外:Date类的使用存在一定的矛盾.

Everything is okay except one little detail in your custom Converter class: there is one incocnsistency with the usage of Date class.

三次使用java.sql.Date作为该类的标识符,但是一次却忘记使用它(implements Converter<LocalDate, Date>),在那里错误地使用了java.utils.Date.

Three times you use java.sql.Date as Identifier of the class, but one time you forgot it (implements Converter<LocalDate, Date>) and there it mistakingly took java.utils.Date.

在其中也添加包路径java.sql.Date可以解决问题

Adding the package path java.sql.Date there as well will do the trick

import com.vaadin.data.Converter;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;

import java.sql.Date;
import java.time.LocalDate;

public class SqlDateToLocalDateConverter implements Converter<LocalDate, java.sql.Date> {

    @Override
    public Result<java.sql.Date> convertToModel(LocalDate value, ValueContext context) {
        if (value == null) {
            return Result.ok(null);
        }
        return Result.ok( java.sql.Date.valueOf(value) );
    }

    @Override
    public LocalDate convertToPresentation(java.sql.Date value, ValueContext context) {
        if (value == null) {
            return LocalDate.now();
        }
        return value.toLocalDate();
    }
}

这篇关于Vaadin DateField将空值保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆