Отметка времени hibernate ogm mongodb

У меня есть следующий mongodb

{
    "_id" : ObjectId("57713c6304f4dc08008b45ba"),
    "SYS_FluxName" : "ERDF_F12_17X100A100F0073T_GRD-F046_0321_00011_FL_00001_00001.xml",
    "SYS_ReadDateTime" : Timestamp(6300883749567463, 83),
    "SYS_BaseNameZip" : "ERDF_F12_17X100A100F0073T_GRD-F046_0321_00011_M_30_20160301223530.zip",
    "SYS_Status" : NumberLong(1),
    "SYS_DateCreaERDF" : "2016-03-01T20:38:48Z"
}

и следующий объект

public class EnlFluxF12Entry  implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="_id")
    private ObjectId id;

    @Column(name="SYS_FluxName")
    public String sysFluxName;

    @Column(name="SYS_ReadDateTime")
    @Temporal(TemporalType.TIMESTAMP)
    public Date sysReadDateTime;

    @Column(name="SYS_BaseNameZip")
    public String sysBaseNameZip;

    @Column(name="SYS_Status")
    public Long sysStatus;

    @Column(name="SYS_DateCreaERDF")
    public String sysDateCreaERDF;

    public ObjectId getId(){
        return id;
    }
...
}

поле public Date sysReadDateTime генерирует исключение при попытке найти ().

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: Could not set field value [TS time:Mon Jun 27 16:46:59 CEST 2016 inc:83] value by reflection : [class com.energielibre.middleware.service.mongodatalayergeneric.beans.EnlFluxF12Entry.sysReadDateTime] setter of com.energielibre.middleware.service.mongodatalayergeneric.beans.EnlFluxF12Entry.sysReadDateTime
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1619)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1106)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1033)
        at org.hibernate.ogm.jpa.impl.OgmEntityManager.find(OgmEntityManager.java:97)
        at com.energielibre.middleware.service.mongodatalayergeneric.Tester.main(Tester.java:30)
Caused by: org.hibernate.PropertyAccessException: Could not set field value [TS time:Mon Jun 27 16:46:59 CEST 2016 inc:83] value by reflection : [class com.energielibre.middleware.service.mongodatalayergeneric.beans.EnlFluxF12Entry.sysReadDateTime] setter of com.energielibre.middleware.service.mongodatalayergeneric.beans.EnlFluxF12Entry.sysReadDateTime
        at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:58)
        at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:607)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:220)
        at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4573)
        at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:172)
        at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:128)
        at org.hibernate.ogm.loader.impl.OgmLoader.initializeEntitiesAndCollections(OgmLoader.java:812)
        at org.hibernate.ogm.loader.impl.OgmLoader.doQuery(OgmLoader.java:393)
        at org.hibernate.ogm.loader.impl.OgmLoader.doQueryAndInitializeNonLazyCollections(OgmLoader.java:283)
        at org.hibernate.ogm.loader.impl.OgmLoader.loadEntity(OgmLoader.java:201)
        at org.hibernate.ogm.loader.impl.OgmLoader.load(OgmLoader.java:157)
        at org.hibernate.ogm.loader.impl.OgmLoader.load(OgmLoader.java:149)
        at org.hibernate.ogm.loader.entity.impl.DynamicBatchingEntityLoaderBuilder$DynamicBatchingEntityLoader.load(DynamicBatchingEntityLoaderBuilder.java:116)
        at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3956)
        at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)
        at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478)
        at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
        at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278)
        at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121)
        at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)
        at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129)
        at org.hibernate.internal.SessionImpl.access$2600(SessionImpl.java:164)
        at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2696)
        at org.hibernate.internal.SessionImpl.get(SessionImpl.java:975)
        at org.hibernate.engine.spi.SessionDelegatorBaseImpl.get(SessionDelegatorBaseImpl.java:630)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1075)
        ... 3 more
Caused by: java.lang.IllegalArgumentException: Can not set java.util.Date field com.energielibre.middleware.service.mongodatalayergeneric.beans.EnlFluxF12Entry.sysReadDateTime to org.bson.types.BSONTimestamp
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
        at java.lang.reflect.Field.set(Field.java:764)
        at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:38)
        ... 28 more

постоянство.xml

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

    <persistence-unit name="primary" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
        <properties>
         <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
            <property name="hibernate.ogm.datastore.provider" value="mongodb" />
            <property name="hibernate.ogm.datastore.database" value="heroku_6tp7jgpd" />
            <property name="hibernate.ogm.datastore.host" value="*****" />
            <property name="hibernate.ogm.datastore.port" value="*****" />
            <property name="hibernate.ogm.datastore.username" value="*****" />
            <property name="hibernate.ogm.datastore.password" value="*****" />
        </properties>
    </persistence-unit>
</persistence>

Должен ли я изменить тип Date на sweet с типом MongoDB Timestamp?


person Med Besbes    schedule 10.01.2017    source источник
comment
Можете ли вы показать нам конфигурацию, которую вы используете?   -  person s7vr    schedule 10.01.2017
comment
Я добавил файл persistence.xml   -  person Med Besbes    schedule 10.01.2017
comment
Вы вставляли данные через hibernate mongo API? Я имею в виду, что BSONTimestamp — это внутренний тип. Вы должны изменить коллекцию mongo db, чтобы использовать BSONDate, и посмотреть, как она работает. Что-то стоящее поиска.   -  person s7vr    schedule 10.01.2017
comment
У меня есть доступ только для чтения к mongoDB, я ничего не могу изменить   -  person Med Besbes    schedule 10.01.2017
comment
Посмотрите, сможете ли вы сопоставить его Длинное значение на вашей стороне   -  person s7vr    schedule 10.01.2017
comment
нет, это не работает   -  person Med Besbes    schedule 10.01.2017
comment
Давайте продолжим обсуждение в чате.   -  person Med Besbes    schedule 10.01.2017
comment
изменение будет на стороне сущности?   -  person Med Besbes    schedule 11.01.2017


Ответы (1)


Проблема с этой проблемой заключается в том, что Timestamp является внутренним типом MongoDB, и Hibernate OGM не имеет способа преобразовать его в тип Java.

Когда вы используете:

@Column(name="SYS_ReadDateTime")
@Temporal(TemporalType.TIMESTAMP)
public Date sysReadDateTime;

Hibernate OGM создаст в БД что-то вроде:

"SYS_ReadDateTime" : "2017/01/11 11:52:28:493 +0000"

У вас есть ошибка, потому что это не так.

Насколько я вижу, на данный момент у вас есть следующие варианты:

  1. Игнорировать поле. Вам действительно нужно это читать? Отметка времени — это внутренний тип MongoDb, и я не уверен, что его следует читать или использовать другими приложениями.

  2. Используйте нативные запросы. Я думаю, что вы могли бы прочитать значение, используя собственные запросы, а затем создать соглашение на Java. Более подробную информацию вы найдете в документация по нативным запросам. Вам не нужно возвращать объект при использовании собственных запросов, это не очень удобно, но может сработать.

  3. Вы можете предоставить патч для Hibernate OGM. В MongoDBDialect#overrideType мы преобразуем тип MongoDB в тип Java. Я думаю, вам нужно что-то похожее на то, что мы делаем для ObjectID. Вы можете ознакомиться с классами в пакете org.hibernate.ogm.datastore.mongodb.type.impl.

  4. Создайте свой собственный диалект, расширяющий MongDBDialect, и переопределите метод MongoDBDialect#overrideType, чтобы можно было преобразовать значение, используемое для метки времени. Затем вы можете использовать свойство hibernate.ogm.datastore.grid_dialect вместо свойства по умолчанию.

Мне жаль, что на данный момент нет более простого способа решить проблему, в нашей дорожной карте мы должны предоставить более общий способ, чтобы пользователь мог передавать пользовательские типы.

person Davide    schedule 11.01.2017