从数据库加载joda LocalTime

时间:2013-03-04 21:26:56

标签: hibernate jodatime

我正在使用Joda Time和Jadira用户类型库来保存我的数据库中的Joda LocalTime。

这是我的实体

@Entity
public class Airport implements Serializable {

    private static final long serialVersionUID = 6382228467347085567L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false)
    @NotNull
    private String nameOACI;

    @Column(nullable = false)
    @NotNull
    private String nameIATA;

    @Column(nullable = false)
    @NotNull
    private int ssliaLevel;

    @Column(nullable = true)
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalTime")
    private LocalTime openingTime;

    @Column(nullable = true)
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalTime")
    private LocalTime closingTime;

    @Column(nullable = false)
    @NotNull
    private String latitude;

    @Column(nullable = false)
    @NotNull
    private String longitude;

    @Column(nullable = false)
    @NotNull
    private int altitude;

    @Column(nullable = true)
    private String comments;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private AirportCategoryE category;

    @Column(nullable = true)
    @NotNull
    @Type(type = "com.flightfaq.dao.converters.MinutesDaoConverter")
    private Minutes taxiTime;

    @Column(nullable = true)
    @NotNull
    @Type(type = "com.flightfaq.dao.converters.MinutesDaoConverter")
    private Minutes depTimeOffset;

    @Column(nullable = true)
    @NotNull
    @Type(type = "com.flightfaq.dao.converters.MinutesDaoConverter")
    private Minutes arrTimeOffset;

    @OneToMany(mappedBy = "airport", cascade = CascadeType.ALL)
    private List<Runway> runways;

    @OneToMany(mappedBy = "airport", cascade = CascadeType.ALL)
    private List<Fueler> fuelers;

    @OneToMany(mappedBy = "airport", cascade = CascadeType.ALL)
    private List<Handling> handlings;

    public Airport() {
        runways = new ArrayList<Runway>();
        fuelers = new ArrayList<Fueler>();
        handlings = new ArrayList<Handling>();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNameOACI() {
        return nameOACI;
    }

    public void setNameOACI(String nameOACI) {
        this.nameOACI = nameOACI;
    }

    public String getNameIATA() {
        return nameIATA;
    }

    public void setNameIATA(String nameIATA) {
        this.nameIATA = nameIATA;
    }

    public int getSsliaLevel() {
        return ssliaLevel;
    }

    public void setSsliaLevel(int ssliaLevel) {
        this.ssliaLevel = ssliaLevel;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }

    public int getAltitude() {
        return altitude;
    }

    public void setAltitude(int altitude) {
        this.altitude = altitude;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public AirportCategoryE getCategory() {
        return category;
    }

    public void setCategory(AirportCategoryE category) {
        this.category = category;
    }

    public Minutes getTaxiTime() {
        return taxiTime;
    }

    public void setTaxiTime(Minutes taxiTime) {
        this.taxiTime = taxiTime;
    }

    public Minutes getDepTimeOffset() {
        return depTimeOffset;
    }

    public void setDepTimeOffset(Minutes depTimeOffset) {
        this.depTimeOffset = depTimeOffset;
    }

    public Minutes getArrTimeOffset() {
        return arrTimeOffset;
    }

    public void setArrTimeOffset(Minutes arrTimeOffset) {
        this.arrTimeOffset = arrTimeOffset;
    }

    public List<Runway> getRunways() {
        return runways;
    }

    public void setRunways(List<Runway> runways) {
        this.runways = runways;
    }

    public List<Fueler> getFuelers() {
        return fuelers;
    }

    public void setFuelers(List<Fueler> fuelers) {
        this.fuelers = fuelers;
    }

    public List<Handling> getHandlings() {
        return handlings;
    }

    public void setHandlings(List<Handling> handlings) {
        this.handlings = handlings;
    }

    public LocalTime getOpeningTime() {
        return openingTime;
    }

    public void setOpeningTime(LocalTime openingTime) {
        this.openingTime = openingTime;
    }

    public LocalTime getClosingTime() {
        return closingTime;
    }

    public void setClosingTime(LocalTime closingTime) {
        this.closingTime = closingTime;
    }

}

这是我的道歉

@Singleton
@Startup
@LocalBean
public class AirportDaoImpl implements AirportDao {

    @PersistenceContext(unitName = "flightfaq")
    protected EntityManager em;

    /** JPQL query to find a {@link Airport} given its OACI name */
    private static final String JPQL_FIND_BY_NAME = "SELECT a FROM Airport a WHERE a.nameOACI=:nameOACI";

    @Override
    public Airport find(String nameOACI) throws DAOException {
        Airport airport = null;
        try {
            TypedQuery<Airport> findQuery = em.createQuery(JPQL_FIND_BY_NAME,
                    Airport.class).setParameter("nameOACI", nameOACI);
            airport = findQuery.getSingleResult();
        } catch (NoResultException e) {
            airport = null;
        } catch (Exception e) {
            throw new DAOException(e);
        }
        return airport;
    }

}

问题在于,当我用有效名称调用DAO时,我得到了

4 mars 2013 21:21:46 org.jadira.usertype.spi.reflectionutils.JavaTimeZoneWorkaroundHelper <clinit>
ATTENTION: Under JDK 6 it may not be possible to handle DST transitions correctly
4 mars 2013 21:21:46 com.sun.faces.lifecycle.InvokeApplicationPhase execute
ATTENTION: #{missionHandler.generateMissionFeasability}: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: 
    com.flightfaq.dao.DAOException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
javax.faces.FacesException: #{missionHandler.generateMissionFeasability}: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: 
    com.flightfaq.dao.DAOException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:117)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:791)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1256)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:680)
Caused by: javax.faces.el.EvaluationException: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: 
    com.flightfaq.dao.DAOException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
    ... 24 more
Caused by: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: 
    com.flightfaq.dao.DAOException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:363)
    at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:283)
    at sun.proxy.$Proxy127.find(Unknown Source)
    at com.flightfaq.beans.managed.MissionHandler.computeFlightTimes(MissionHandler.java:314)
    at com.flightfaq.beans.managed.MissionHandler.generateMissionFeasability(MissionHandler.java:212)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 25 more
Caused by: com.flightfaq.dao.DAOException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at com.flightfaq.dao.impl.AirportDaoImpl.find(AirportDaoImpl.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
    at org.apache.openejb.cdi.CdiInterceptor.invoke(CdiInterceptor.java:128)
    at org.apache.openejb.cdi.CdiInterceptor.access$000(CdiInterceptor.java:43)
    at org.apache.openejb.cdi.CdiInterceptor$1.call(CdiInterceptor.java:64)
    at org.apache.openejb.cdi.CdiInterceptor.aroundInvoke(CdiInterceptor.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
    at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:176)
    at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:95)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
    at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:176)
    at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:95)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
    at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:138)
    at org.apache.openejb.core.singleton.SingletonContainer._invoke(SingletonContainer.java:244)
    at org.apache.openejb.core.singleton.SingletonContainer.invoke(SingletonContainer.java:211)
    at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:253)
    at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:248)
    at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:92)
    at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:279)
    ... 36 more
Caused by: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:273)
    at com.flightfaq.dao.impl.AirportDaoImpl.find(AirportDaoImpl.java:34)
    ... 75 more
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime
    at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:151)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:707)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:371)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4463)
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:186)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:134)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1103)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:960)
    at org.hibernate.loader.Loader.doQuery(Loader.java:910)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
    at org.hibernate.loader.Loader.doList(Loader.java:2516)
    at org.hibernate.loader.Loader.doList(Loader.java:2502)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
    at org.hibernate.loader.Loader.list(Loader.java:2327)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1247)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
    ... 76 more
Caused by: java.lang.IllegalArgumentException: Can not set org.joda.time.LocalTime field com.flightfaq.beans.business.Airport.closingTime to org.joda.time.LocalTime
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
    at java.lang.reflect.Field.set(Field.java:657)
    at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:139)
    ... 95 more

正如您在堆栈末尾看到的那样,有

Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.flightfaq.beans.business.Airport.closingTime

但也

Can not set org.joda.time.LocalTime field com.flightfaq.beans.business.Airport.closingTime to org.joda.time.LocalTime

这是我用来输入数据库中有问题的机场的SQL命令

INSERT INTO `Airport` (`id`, `altitude`, `arrTimeOffset`, `category`, `closingTime`, `comments`, `depTimeOffset`, `latitude`, `longitude`, `nameIATA`, `nameOACI`, `openingTime`, `ssliaLevel`, `taxiTime`) VALUES
(1, 499, '0', 'A', '00:00:00', 'se garer au parking R12', '15', '433806N', '0012204E', 'TLS', 'LFBO', '00:00:00', 4, '0');

我在关闭时间进入'00:00:00'。

1 个答案:

答案 0 :(得分:0)

closingTime的数据库中应该有time类型 如果您想在数据库中使用varchar[]类型,那么您应该使用自己的usertype

应该看起来像

public class LocalTimeType implements UserType {
    public int[] sqlTypes() {
        return new int[] {
                Types.VARCHAR,
        };
    }

    public Class getReturnedClass() {
        return LocalTime.class;
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
       ...
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException {
      ...
    }

    ...
}