在使用Spring Data JPA时,遇到了一个报错:

org.springframework.beans.factory.BeanCreationException: 
  Error creating bean with name 'entityManagerFactory' defined in class path resource 
  [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: 
    Invocation of init method failed; nested exception is org.hibernate.DuplicateMappingException: 
      Table [classify] contains physical column name [parent_uuid] 
      referred to by multiple logical column names: [parent_uuid], [parentUuid]

出现问题的实体是这样的:

@Entity(name = "classify")
public class Classify {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
    private String uuid;
    
    private String parentUuid;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "parent_uuid")
    @JsonBackReference
    private Classify parent;

    @OneToMany(mappedBy = "parent",fetch = FetchType.LAZY)
    private List<Classify> children;

    /** 已省略无关内容 **/
}

这个实体本来是打算通过自关联来实现无限极分类,parentUuid是后来为了方便前端操作父节点而加入的。

原因分析

通过报错信息,我们可以看到问题就发生在parentUuid这里。在当前项目所使用的JPA版本中,框架会将parentUuid映射为parent_uuid(示例代码中没有明确指定对应的字段名,不推荐这种写法)。而下面的parent,框架实际上是通过在数据库表中新建一个parent_uuid存放其对应的主键uuid来实现的。

这里我们可以看到,实体中存在parentUuidparent都同时对应了parent_uuid。从报错来看,这种写法显然是不行的。

解决方法

通过面向百度编程,发现了一个解决办法:

Table [] contains logical column name [] referenced by multiple physical column names: [], [] 建表异常

我们只需要在parentUuid中加上如下注释即可(同时补上了对应的字段名):

    @Column(name = "parent_uuid",insertable = false, updatable = false)
    private String parentUuid;

这里没有仔细地去分析为什么要这样做。根据添加的注解属性来看,初步猜测是JPA做了一些校验工作。如果实体中出现多个属性对应了同个字段,那么其余的属性对此字段要设置为不可修改的(只读的)。如果有朋友知道更准确的说法的话,欢迎补充!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐