В моем PostgreSQL 12.2 + PostGIS 2.5.4 у меня есть таблица с именем Address и столбцом типа geography(POINT, 4326)
.
Я работаю с Hibernate Spatial и пытаюсь разработать конвертер атрибутов для создания ожидаемого объекта Point из моего объекта SpatialLocation.
SpatialLocation в основном содержит информацию о координатах:
@Data
@Accessors(chain = true)
public class SpatialLocation {
private Double latitude;
private Double longitude;
}
Вот компонент PointFactory, который я сделал:
public class PointFactory extends GeometryFactory {
public Point createPointFromSpatialLocation(SpatialLocation spatialLocation) {
final Coordinate coordinate = new Coordinate(spatialLocation.getLatitude(), spatialLocation.getLongitude());
return createPoint(coordinate);
}
}
Вот PointConverter:
@Component
public class PointConverter implements AttributeConverter<SpatialLocation, Point> {
@Autowired
private PointFactory pointFactory;
@Override
public Point convertToDatabaseColumn(SpatialLocation spatialLocation) {
return pointFactory.createPointFromSpatialLocation(spatialLocation);
}
@Override
public SpatialLocation convertToEntityAttribute(Point point) {
return new SpatialLocation()
.setLatitude(point.getCoordinate().x)
.setLongitude(point.getCoordinate().y);
}
}
Вот как атрибут устанавливается в классе адресов:
@Convert(converter = PointConverter.class)
@Column(columnDefinition = "geography(POINT, 4326)")
private SpatialLocation spatialLocation;
В службе адрес создается и сохраняется следующим образом:
@Transactional
public Address saveAddress(final AddressRequest addressRequest) {
final City city = findOrCreateNewCityService.findOrCreateNewCity(addressRequest.getCityRequest());
final Address addressToPersist = modelMapper.map(addressRequest, Address.class)
.setSpatialLocation(modelMapper.map(addressRequest.getSpatialLocationRequest(), SpatialLocation.class))
.setCity(city);
log.info("Creating a new Address: '{}'", addressToPersist);
return addressRepository.save(addressToPersist);
}
При попытке создать новый адрес возникает следующая ошибка:
org.hibernate.HibernateException: Unknown unwrap conversion requested: com.vividsolutions.jts.geom.Geometry to [B
at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.unknownUnwrap(AbstractTypeDescriptor.java:98) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.spatial.JTSGeometryJavaTypeDescriptor.unwrap(JTSGeometryJavaTypeDescriptor.java:70) ~[hibernate-spatial-5.3.16.Final.jar:5.3.16.Final]
at org.hibernate.spatial.JTSGeometryJavaTypeDescriptor.unwrap(JTSGeometryJavaTypeDescriptor.java:26) ~[hibernate-spatial-5.3.16.Final.jar:5.3.16.Final]
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$1.doBind(VarbinaryTypeDescriptor.java:45) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter$1.bind(AttributeConverterSqlTypeDescriptorAdapter.java:88) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:271) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2929) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3226) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3760) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:na]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:443) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3202) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:534) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:631) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
Когда я напрямую создайте объект Point без использования конвертера, он работает как положено.
Вот некоторые другие важные детали проекта:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>5.3.16.Final</version>
</dependency>
jpa:
database-platform: org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect