You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JHipster生成一对多关联引发异常的原因排查与修复咨询

JHipster JDL代码问题分析与修复

问题描述

编写的JDL代码

entity A {
  name String required
}

entity B {
  name String unique required,
}

relationship OneToMany {
  B{children} to A{owner}
}

application {
  config {
    applicationType monolith
    databaseType sql
  }
  entities *
  dto * with mapstruct
  service * with serviceClass
}

遇到的问题

1. MapStruct编译警告

/src/main/java/foo/service/mapper/A.java:13: 警告: 未映射目标属性: "children, removeChildren"。从属性"BDTO owner"映射到"B owner"。发生在'EntityMapper'的'E toEntity(D dto)'方法中。
public interface A extends EntityMapper<ADTO, A> {
^
/src/main/java/foo/service/mapper/AMapper.java:13: 警告: 未映射目标属性: "children, removeChildren"。从属性"BDTO owner"映射到"B owner"。发生在'EntityMapper'的'void partialUpdate(E entity, D dto)'方法中。
public interface AMapper extends EntityMapper<ADTO, A> {
^
/src/main/java/foo/service/mapper/BMapper.java:13: 警告: 未映射目标属性: "children, removeChildren"。发生在'EntityMapper'的'E toEntity(D dto)'方法中。
public interface BMapper extends EntityMapper<BDTO, B> {
^
/src/main/java/foo/service/mapper/BMapper.java:13: 警告: 未映射目标属性: "children, removeChildren"。发生在'EntityMapper'的'void partialUpdate(E entity, D dto)'方法中。
public interface ModelMapper extends EntityMapper<BDTO, B> {
^
4 条警告

2. Hibernate运行时异常

ERROR 30510 --- [ XNIO-1 task-3] foo.service.AService : findAll()方法中出现异常,原因='org.hibernate.exception.SQLGrammarException: could not prepare statement',异常信息='could not prepare statement; SQL [select a0_.id as id1_1_, a0_.name as name2_1_, a0_.owner_id as owner_id4_1_, a0_.value as value3_1_ from a a0_]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement'
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select a0_.id as id1_1_, a0_.name as name2_1_, a0_.owner_id as owner_id4_1_, a0_.value as value3_1_ from a a0_]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy3/jdk.proxy3.$Proxy200.findAll(Unknown Source)
at foo.service.AService.findAll(AService.java:88)
at foo.service.AService$$FastClassBySpringCGLIB$$4afc8e16.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
....

修复方案

一、MapStruct警告修复

警告根源是JDL默认生成的DTO未包含关联集合属性的映射规则。实体B的children是关联集合,MapStruct无法自动识别映射,需手动在JDL中指定:

  1. 修改JDL的DTO配置
    将原有的dto * with mapstruct替换为更精确的配置,明确包含关联字段:

    dto A with mapstruct {
      name, owner
    }
    dto B with mapstruct {
      name, children
    }
    

    或者如果需要保留批量生成,单独为B补充字段:

    dto * with mapstruct
    dto B with mapstruct {
      children
    }
    
  2. 重新生成代码
    运行jhipster import-jdl <你的JDL文件名>.jh,重新生成后MapStruct会自动生成children和removeChildren的映射逻辑,警告即可消除。

二、Hibernate SQL异常修复

从SQL语句select ... a0_.value ...可以看出,Hibernate在查询实体A时尝试访问value字段,但你的JDL中实体A并没有定义这个属性,说明数据库表结构与当前实体类不匹配:

  1. 排查原因
    大概率是之前生成过带value属性的实体A,后来删除该属性但数据库表未同步更新,导致Hibernate映射出错。

  2. 修复方式

    • 开发环境快速修复:清空数据库,重新运行代码生成,让JHipster重建正确的表结构。
    • 生产/测试环境修复:执行SQL删除冗余字段:
      ALTER TABLE a DROP COLUMN value;
      
    • 标准JHipster流程:使用Liquibase创建数据库迁移脚本,在src/main/resources/config/liquibase/changelog目录下新增变更日志文件,添加删除字段的配置,启动应用时自动执行迁移。

三、JDL代码优化

实体B的定义末尾多了一个冗余逗号,虽然不影响生成,但建议修正:

entity B {
  name String unique required  // 去掉末尾的逗号
}

内容的提问来源于stack exchange,提问作者juwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:25:32