EDITHibernate XML映射 - Nullable Integer

时间:2016-03-03 17:56:52

标签: java xml hibernate

我遇到了Hibernate映射的问题,我知道有很多关于这个主题的帖子,而且我读了很多这些帖子,但我仍然无法解决它。

对于在Integer上映射的字段,我有一个NULL值,当我执行select时,我收到此错误:

Mar 3, 2016 4:11:24 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalArgumentException
    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:622)
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:66)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:583)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:229)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3848)
    at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:152)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
    at org.hibernate.loader.Loader.doQuery(Loader.java:857)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2542)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
    at com.squire.svi.billing.dao.BillingItemDAO.fetch(BillingItemDAO.java:42)
    at com.squire.svi.billing.model.BillingItemModel.updateDataFromDatabase(BillingItemModel.java:191)
    at com.squire.svi.billing.model.BillingItemModel.fetchData(BillingItemModel.java:121)
    at com.squire.svi.billing.model.BillingItemModelFactory.getBillingItemModel(BillingItemModelFactory.java:212)
    at com.squire.svi.billing.BillingMgr.setBillingItemModel(BillingMgr.java:1339)
    at com.squire.svi.billing.BillingMgr.doBillingTableLink(BillingMgr.java:1324)
    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:622)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
    at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
    at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:78)
    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:57)
    at javax.faces.component.UICommand.broadcast(UICommand.java:127)
    at org.ajax4jsf.component.AjaxActionComponent.broadcast(AjaxActionComponent.java:55)
    at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:329)
    at org.ajax4jsf.component.AjaxViewRoot.broadcastEventsForPhase(AjaxViewRoot.java:304)
    at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:261)
    at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:474)
    at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:183)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
    at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
    at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:769)
    at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:698)
    at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:891)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
    at java.lang.Thread.run(Thread.java:701)

以下是映射:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 14-Feb-2011 16:39:32 by Hibernate Tools 3.2.5.Beta -->
<hibernate-mapping>
    <class name="com.squire.svi.billing.Routing" table="Routing" lazy="false">

        [...]

        <property name="timeOfDayGroupId" type="java.lang.Integer" not-null="false" length="5">
            <column name="TODGroupId" default="0" />
        </property>

        [...]

    </class>
</hibernate-mapping>

该表如下,映射列是最后一列:

mysql> describe Routing;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| Id              | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| Prefix          | varchar(30)      | NO   | MUL | NULL    |                |
| Route           | int(10) unsigned | NO   | MUL | NULL    |                |
| Cost            | decimal(13,4)    | YES  | MUL | 0.0000  |                |
| Priority        | int(10)          | YES  | MUL | 0       |                |
| Loadshare       | tinyint(1)       | YES  |     | 0       |                |
| LoadBalance     | tinyint(1)       | YES  | MUL | 0       |                |
| OnNet           | tinyint(1)       | YES  |     | 0       |                |
| country_code    | varchar(40)      | YES  |     | NULL    |                |
| routing_info    | varchar(40)      | YES  |     | NULL    |                |
| Outgoing_Format | varchar(40)      | YES  |     | NULL    |                |
| RoutePlanId     | int(10) unsigned | YES  |     | NULL    |                |
| EnableTBR       | tinyint(1)       | YES  |     | 0       |                |
| TODGroupId      | int(5)           | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
mysql> select * from Routing;
+----+--------+-------+--------+----------+-----------+-------------+-------+--------------+--------------+-----------------+-------------+-----------+------------+
| Id | Prefix | Route | Cost   | Priority | Loadshare | LoadBalance | OnNet | country_code | routing_info | Outgoing_Format | RoutePlanId | EnableTBR | TODGroupId |
+----+--------+-------+--------+----------+-----------+-------------+-------+--------------+--------------+-----------------+-------------+-----------+------------+
|  2 | ewqe   |     2 | 0.0000 |        0 |         0 |           0 |  NULL | NULL         | NULL         | NULL            |        NULL |         1 |       NULL |
|  7 | 0%     |     2 | 0.0000 |        2 |         0 |           0 |  NULL | NULL         | NULL         | NULL            |        NULL |         0 |          0 |
+----+--------+-------+--------+----------+-----------+-------------+-------+--------------+--------------+-----------------+-------------+-----------+------------+
2 rows in set (0.00 sec)

我的bean上的setter如下:

private Integer timeOfDayGroupId;

public void setTimeOfDayGroupId(Integer timeOfDayGroupId) {
    LoggingManager.logGeneral("setTimeOfDayGroupId "+timeOfDayGroupId);
    if(null != timeOfDayGroupId){
        this.timeOfDayGroupId = timeOfDayGroupId;

    }else{
        this.timeOfDayGroupId = 0;
    }

    LoggingManager.logGeneral("timeOfDayGroupId "+this.timeOfDayGroupId);
}   

我也尝试使用int作为参数。 但是第一行的日志记录从未被调用过,我首先得到了异常

如果我将TODGroupId值设置为0,那么它可以正常工作。所以这个NULL就是问题。

欢迎任何想法。

由于

编辑:实体类

package com.squire.svi.billing;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

import org.apache.commons.lang.builder.ToStringBuilder;

import com.squire.svi.cache.Cacheable;
import com.squire.svi.logging.LoggingManager;
import com.squire.svi.util.StringSortable;

public class Routing extends SelectItem implements Serializable, BillingItem,
    Cacheable<String>, StringSortable {

    private static final long serialVersionUID = 1L;

    /** identifier field */
    private Integer id;

    /** persistent field */
    private String prefix; // also used as the name for this object

    /** persistent field, this is shown as the route on the display */
    private com.squire.svi.billing.Customer customer;

    private Double cost;
    private Integer priority;
    private Integer percentage;
    private Double quality;
    private String routeBy;
    private Boolean loadshare;
    private Boolean onNet;
    private boolean enableTBR;
    private Integer timeOfDayGroupId;
    private com.squire.svi.billing.Routeplan routeplan;

    public Boolean getLoadshare() {
        return loadshare;
    }

    public Boolean isLoadshare() {
        return loadshare;
    }

    public void setLoadshare(Boolean loadshare) {
        this.loadshare = loadshare;
    }

    public boolean getEnableTBR() {
        return isEnableTBR();
    }

    public boolean isEnableTBR() {
        return enableTBR;
    }

    public void setEnableTBR(boolean enableTBR) {
        this.enableTBR = enableTBR;
    }

    public int getTimeOfDayGroupId() {
        LoggingManager.logGeneral("getTimeOfDayGroupId "+timeOfDayGroupId);
        return timeOfDayGroupId;
    }

    public void setTimeOfDayGroupId(Integer timeOfDayGroupId) {
        LoggingManager.logGeneral("setTimeOfDayGroupId integer "+timeOfDayGroupId);
        if(null != timeOfDayGroupId){
            this.timeOfDayGroupId = timeOfDayGroupId;

        }else{
            this.timeOfDayGroupId = 0;
        }

        LoggingManager.logGeneral("timeOfDayGroupId "+this.timeOfDayGroupId);
    }   

[...]

}

编辑:从映射中删除默认值后,我仍然有同样的错误。

<property name="timeOfDayGroupId" type="java.lang.Integer" not-null="false" length="5">
    <column name="TODGroupId" />
</property>

再次编辑:以这种方式编写映射

<property name="timeOfDayGroupId" type="integer">
  <column name="TODGroupId" not-null="false" default="null" />
</property>

感谢newohybat。

1 个答案:

答案 0 :(得分:0)

从数据库反序列化实体并调用实体的setter时抛出异常。

我怀疑Hibernate不期望数据库中有NULL值,因为它依赖于在INSERT上插入默认值的事实。这必须在数据库中得到保证。

所以我的建议是在从Hibernate查询之前让表进入预期状态(默认值而不是NULL)。