java - Spring 中使用 HibernateTemplate 的 ModelMapper 的奇怪行为

标签 java spring hibernate spring-mvc modelmapper

我对 ModelMapper 框架与 Spring 和 Hibernate 4 相结合的行为感到非常奇怪。经过 2 天的搜索,我仍然有点困惑,无法弄清楚这种奇怪行为的原因。

我有 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;
}

在我的 Controller 中,我有以下代码:

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

问题出在数据库被删除并重新创建后首次运行的查询中。 我删除数据库并运行我的应用程序,并添加 A 类和 B 类的新对象。然后,当我尝试列出表中的所有对象时,ModelMapper 返回 null 代替 User 类对象。每次第一次运行都会返回 null。当我重新启动应用程序时,用户已正确映射。此外,当我使用 UserController 返回所有用户时,所有用户都正确返回并且所有属性都正确映射。 更重要的是,B 类的对象包含 A 类的关系,并且即使在应用程序第一次运行时,这些 A 类对象也会正确返回。

这些实体是急切加载的,因此 hibernate 必须加载它。 当我使用标准转换器将 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

模型映射器配置:

@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>

谁能帮我解答一下吗?有什么想法我可以检查什么以及这种奇怪行为的原因是什么?

附注想要只使用 User 类来 udnerline。其他类(class)运行良好。

最佳答案

您还需要将映射添加到模型映射器,以防您没有在配置类中这样做 -

modelMapper.addMappings(new OutputMapper());

您在定义模型映射器时检索配置,但考虑重写 PropertyMap 的 configure() 方法以单独映射您的属性:

class OutputMapper extends PropertyMap<AData, Output> {

   @Override
   protected void configure(){

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

   }
}

关于java - Spring 中使用 HibernateTemplate 的 ModelMapper 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41038645/

相关文章:

java - 为什么手动连接 OSGi 服务不是一个好主意?

spring boot 数据 cassandra 响应式(Reactive) JmxReporter 问题

java - 即使您在内部使用类级别变量,使用@Autowired anno并且从不在bean上调用set方法是否可以提供线程安全性?

java - spring mvc dao 和服务 bean 映射

java - 无法在Android中同一类中的方法之间传递值

java - 查找连续数组中的第 k 个缺失元素(超出时间限制)

java - hibernate : No Dialect mapping for JDBC type: 101

Java Spring Tomcat : Custom DataSource Factory Being Ignored

java - Hibernate在使用@GenerateValue(strategy=GenerationType.AUTO)时不保存对象

java - Hibernate 用于获取子选择的原始整数列表