@Converter(introduced since JPA2.1)
представляется очень удобным способом переключения значений базы данных на значение, которое мы хотим видеть в нашем Java-коде. Однако я не могу заставить эту работу работать. JPA, похоже, не знает о конвертере, который я написал, и сам пытается преобразовать значения в соответствующий класс.
Это код, который я написал:
@Converter(autoApply = true)
public class DateConverter implements AttributeConverter<Date, String> {
@Override
public String convertToDatabaseColumn(Date b) {
System.out.println("Converting to Database Columns");
return "";
}
@Override
public Date convertToEntityAttribute(String string) {
System.out.println("Converting to Entity Attribute");
return new Date();
}
}
Соответствующая часть, написанная в модели:
@Entity
@Table(name = "test_table")
public class TestClass extends BaseModel {
private static final long serialVersionUID = 1L;
@Id
private Integer id;
@Convert(converter = DateConverter.class)
@Column(name = "is_dominant_project_unit_type")
private Date isDominantProjectUnitType;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getIsDominantProjectUnitType() {
return isDominantProjectUnitType;
}
public void setIsDominantProjectUnitType(Date isDominantProjectUnitType) {
this.isDominantProjectUnitType = isDominantProjectUnitType;
}
}
При выполнении запроса я получаю следующую ошибку:
com.abcd.exception.ProAPIException: java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query
at com.abcd.data.service.trend.TrendService.getPaginatedTrend(TrendService.java:111) ~[classes/:na]
at com.abcd.data.service.trend.TrendService.getHithertoPaginatedTrend(TrendService.java:167) ~[classes/:na]
at com.abcd.data.mvc.trend.TrendController.getHithertoTrend(TrendController.java:183) ~[classes/:na]
at com.abcd.data.mvc.trend.TrendController$$FastClassByCGLIB$$44adcd0f.invoke(<generated>) ~[spring-core-3.2.2.RELEASE.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at com.abcd.data.mvc.trend.TrendController$$EnhancerByCGLIB$$faeff680.getHithertoTrend(<generated>) ~[spring-core-3.2.2.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_55]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_55]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_55]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_55]
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) [shiro-web-1.2.1.jar:1.2.1]
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) [shiro-web-1.2.1.jar:1.2.1]
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) [shiro-core-1.2.1.jar:1.2.1]
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) [shiro-core-1.2.1.jar:1.2.1]
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) [shiro-core-1.2.1.jar:1.2.1]
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) [shiro-web-1.2.1.jar:1.2.1]
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.2.1.jar:1.2.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) [tomcat-embed-core-7.0.37.jar:7.0.37]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-embed-core-7.0.37.jar:7.0.37]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_55]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_55]
Caused by: java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query
at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:1.7.0_55]
at java.util.concurrent.FutureTask.get(FutureTask.java:188) ~[na:1.7.0_55]
at com.abcd.data.service.trend.TrendService.getPaginatedTrend(TrendService.java:100) ~[classes/:na]
... 52 common frames omitted
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:273) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getResultList(CriteriaQueryCompiler.java:254) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
at com.abcd.data.model.filter.JPAQueryBuilder.retrieveResults(JPAQueryBuilder.java:333) ~[classes/:na]
at com.abcd.data.repo.trend.TrendDao.getTrend(TrendDao.java:33) ~[classes/:na]
at com.abcd.data.repo.trend.TrendDao$$FastClassByCGLIB$$b47f3dbd.invoke(<generated>) ~[spring-core-3.2.2.RELEASE.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) ~[spring-tx-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.cache.interceptor.CacheInterceptor$1.invoke(CacheInterceptor.java:58) ~[spring-context-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:214) ~[spring-context-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66) ~[spring-context-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at com.abcd.data.repo.trend.TrendDao$$EnhancerByCGLIB$$664630bd.getTrend(<generated>) ~[spring-core-3.2.2.RELEASE.jar:na]
at com.abcd.data.service.trend.TrendService.getTrend(TrendService.java:56) ~[classes/:na]
at com.abcd.data.service.trend.TrendService.getTrend(TrendService.java:61) ~[classes/:na]
at com.abcd.data.service.trend.TrendService$1.call(TrendService.java:80) ~[classes/:na]
at com.abcd.data.service.trend.TrendService$1.call(TrendService.java:77) ~[classes/:na]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) ~[na:1.7.0_55]
... 3 common frames omitted
Caused by: org.hibernate.exception.GenericJDBCException: could not execute query
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2525) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2508) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2338) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.list(Loader.java:2333) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1269) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
... 23 common frames omitted
Caused by: java.sql.SQLException: Cannot convert value 'testString' from column 2 to TIMESTAMP.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ResultSetRow.getTimestampFast(ResultSetRow.java:1404) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ByteArrayRow.getTimestampFast(ByteArrayRow.java:127) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ResultSetImpl.getTimestampInternal(ResultSetImpl.java:6592) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ResultSetImpl.getTimestamp(ResultSetImpl.java:6192) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ResultSetImpl.getTimestamp(ResultSetImpl.java:6230) ~[mysql-connector-java-5.1.25.jar:na]
at com.mchange.v2.c3p0.impl.NewProxyResultSet.getTimestamp(NewProxyResultSet.java:3394) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$2.doExtract(TimestampTypeDescriptor.java:67) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.hql.QueryLoader.getResultRow(QueryLoader.java:443) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.hql.QueryLoader.getResultColumnOrRow(QueryLoader.java:427) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:740) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.processResultSet(Loader.java:942) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:910) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2522) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
... 32 common frames omitted
Caused by: java.lang.NumberFormatException: testString
at com.mysql.jdbc.StringUtils.getInt(StringUtils.java:791) ~[mysql-connector-java-5.1.25.jar:na]
at com.mysql.jdbc.ResultSetRow.getTimestampFast(ResultSetRow.java:1347) ~[mysql-connector-java-5.1.25.jar:na]
... 49 common frames omitted
Я нашел ссылки для явного регистрации преобразователя в persistence.xml
. Но я пока не использую persistence.xml и хочу продолжить этот путь. Мои классы моделей с аннотацией @Entity
обнаруживаются автоматически. Это код, который я использую для этого:
factory.setPackagesToScan("com.abcd.data.model")
Все мои классы @Entity
внутри этого пакета (или любого подпакета) обнаруживаются. Но не по DateConverter аннотируется с помощью @Converter
. Что мне здесь не хватает.
Я также попытался добавить в свойства следующие свойства:
Properties properties = new Properties();
properties.put("hibernate.archive.autodetection", "class, hbm");
factory.setJpaProperties(properties);
PS: Пожалуйста, не вдавайтесь в подробности, почему я хочу преобразовать случайную строку в дату. Это всего лишь пример.