2016-12-08 2 views
3

У меня действительно странное поведение Framework ModelMapper в сочетании с Spring и Hibernate 4. И после двух дней поиска через SO я все еще немного запутался и не могу понять причину такое странное поведение.Странное поведение ModelMapper, используемое весной с HibernateTemplate

У меня есть 3 класса: класс A, класс B и класс пользователя.

Класс пользователя:

@Entity 
@Table(name = "users") 
@Data 
@EqualsAndHashCode(of = "id") 
@NoArgsConstructor 
@AllArgsConstructor 
@Builder 
public class User implements UserDetails { 
    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    private String id; 

... 
} 

Класс B:

@Entity 
@Audited 
@Table 
@Data 
@Builder 
@EqualsAndHashCode(of = "id") 
@AllArgsConstructor 
@NoArgsConstructor 
public class B implements Serializable{ 

    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    private String id; 

... 

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "user_id") 
    private User user; 

    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(/*some join definition*/) 
    private Set<A> a; 
} 

Класс A:

@Entity 
@Audited 
@Table 
@Data 
@Builder 
@EqualsAndHashCode(of = "id") 
@AllArgsConstructor 
@NoArgsConstructor 
public class A implements Serializable{ 
    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    private String id; 

    ... 
    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "user_id") 
    private User user; 

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 
    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(/*some join definition*/) 
    private Set<User> subscribers; 
} 

В мой контроллер у меня есть ниже код:

List<B> bObjects = bService.findAll(); 
return modelMapper.map(bObjects, new TypeToken<List<BDto>>() { 
}.getType()); 

И проблема в первом запросе запуска после того, как база данных была удалена и воссоздана. Я отбрасываю базу данных и запускаю свое приложение и добавляю новые объекты класса А и В. И затем, когда я пытаюсь перечислить все объекты, которые находятся в моей таблице, ModelMapper возвращает null вместо объекта класса User. Каждый первый запуск возвращает null. Когда я перезапускаю приложение, пользователи правильно отображаются. Более того, когда я использую UserController для возвращения всех пользователей, все пользователи возвращаются по-разному, а все свойства правильно сопоставлены. Более интенсивно, что объекты класса B содержат взаимосвязь класса A, и этот объект класса A возвращается корректно даже в первом запуске приложения.

Эти объекты загружены с нетерпением, поэтому спящий режим должен загрузить его. Когда я использую стандартный конвертер для преобразования A в AD, все работает отлично. Преобразователь содержит жёстко прописанную строку:

aDtoObject.setUserDto(aObject.getUser()); 

Я вставку пользователей по умолчанию в моем классе ApplicationStartUp.

Мои Hibernate свойства конфигурации:

hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect 
hibernate.showSql=false 
hibernate.formatSql=false 
hibernate.hbm2ddl.auto=update 
hibernate.jdbc.batchSize=100 
hibernate.orderInserts=true 
hibernate.orderUpdates=true 
hibernate.jdbc.batchVersionedData=true 
hibernate.ejb.event.post-insert = org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener 
hibernate.ejb.event.post-update = org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener 
hibernate.ejb.event.post-delete = org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener 
hibernate.ejb.event.pre-collection-update = org.hibernate.envers.event.AuditEventListener 
hibernate.ejb.event.pre-collection-remove = org.hibernate.envers.event.AuditEventListener 
hibernate.ejb.event.post-collection-recreate = org.hibernate.envers.event.AuditEventListener 

ModelMapper конфигурации:

@Configuration 
public class ModelMapperConfig { 

    @Bean 
    public ModelMapper strictModelMapper() { 
     ModelMapper modelMapper = new ModelMapper(); 
     modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD); 
     return modelMapper; 
    } 
} 

POM:

 <spring-version>4.2.4.RELEASE</spring-version> 
     <hibernate-version>4.3.8.Final</hibernate-version> 

    <dependency> 
     <groupId>org.modelmapper</groupId> 
     <artifactId>modelmapper</artifactId> 
     <version>0.7.5</version> 
    </dependency> 


    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>${hibernate-version}</version> 
    </dependency> 


    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-envers</artifactId> 
     <version>${hibernate-version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>${hibernate-version}</version> 
    </dependency> 

Может кто-нибудь помочь мне, чтобы понять это? Любые идеи, что я могу проверить и что может быть причиной такого странного поведения?

P.S. если унднерлайн просто с классом User. Другие классы работают нормально.

ответ

0

Кроме того, необходимо добавить отображения в вашей модели картографа, упаковывают вы еще не сделали, что в вашем классе конфигурации -

modelMapper.addMappings(new OutputMapper()); 

Вы запрашиваете конфигурации при определении модели картографа, но рассмотрим переопределение Configure() метод PropertyMap для индивидуальной настройки ваших атрибутов:

class OutputMapper extends PropertyMap<AData, Output> { 

    @Override 
    protected void configure(){ 

    map().setABCD(source.getABCD()); 

    } 
}