springboot jpa oracle实体类中配置注解无法在数据库中生成注释的一种解决方式

需求

对于oracle数据库,jpaEntity即使配置了注释注解@Column(columnDefinition = '列注释'),无法在数据库层生成列的注释

解决方案

自定义注解,配置在Entity类上,项目初始化时,通过EntityManager获取所有的实体类,遍历实体类中是否配置了注解,如果配置了,动态拼接DDL语句并执行

  • 自定义注解:

    import java.lang.annotation.*;
    /**
    * description: * 解决jap根据实体类创建建表过程中无法添加字段注释
    * @author MorningSun
    * @version 1.0 * @since JDK1.8 * date 11/6/2020 10:45 AM */@Target({ElementType.TYPE, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface JPAOracleComment {
       /**
    * spring jpa + oracle add comment * @return */ String value() default "";
    }
    import com.orient.cssrc.jpa.model.JpaOracleComment;
    import lombok.extern.slf4j.Slf4j;
    import org.hibernate.SessionFactory;
    import org.hibernate.internal.SessionFactoryImpl;
    import org.hibernate.persister.entity.EntityPersister;
    import org.hibernate.persister.entity.SingleTableEntityPersister;
    import org.hibernate.persister.walking.spi.AttributeDefinition;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Component;
    import javax.annotation.Resource;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.PersistenceContext;
    import java.lang.reflect.Field;
    import java.util.Map;
    import java.util.Objects;
    /**
    * description: * * @author MorningSun * @version V1.0 * @since date 2020/12/25 */@Slf4j
    @Component
    public class JpaOracleCommentInit implements CommandLineRunner {
       @PersistenceContext
    private EntityManager entityManager;
       @Resource
    private JdbcTemplate jdbcTemplate;
       @Resource
    private HibernateProperties hibernateProperties;
       @Override
    public void run(String... args) throws Exception {
           String ddlAuto = this.hibernateProperties.getDdlAuto();
           if(Objects.nonNull(ddlAuto) && "update".equalsIgnoreCase(ddlAuto)){
               this.scanCommentAnnotationOnEntityAndCreate();
           }
       }
       private void scanCommentAnnotationOnEntityAndCreate(){
           EntityManagerFactory entityManagerFactory = this.entityManager.getEntityManagerFactory();
           SessionFactoryImpl sessionFactory = (SessionFactoryImpl)entityManagerFactory.unwrap(SessionFactory.class);
           Map persisterMap = sessionFactory.getMetamodel().entityPersisters();
           if(Objects.nonNull(persisterMap) && persisterMap.keySet().size() > 0){
               for(Map.Entry entry: persisterMap.entrySet()){
                   Class targetClazz = entry.getValue().getMappedClass();
                   SingleTableEntityPersister persister = (SingleTableEntityPersister)entry.getValue();
                   //数据表名
    String tableName = persister.getTableName();
                   //添加表的注释
    JpaOracleComment targetClazzAnno = targetClazz.getAnnotation(JpaOracleComment.class);
                   if(Objects.nonNull(targetClazzAnno)){
                       String sql = "comment on table " +
                               tableName +
                               " is " +
                               "'" + targetClazzAnno.value() + "'";
                       this.jdbcTemplate.execute(sql);
                   }
                   for (AttributeDefinition attributeDefinition : persister.getAttributes()) {
                       //属性名称
    String propertyName = attributeDefinition.getName();
                       if (propertyName.equalsIgnoreCase("_identifierMapper")) {
                           log.warn("尝试为实体类:" + targetClazz.getSimpleName() + "生成注解,发现了联合主键,暂时无法处理,已忽略对应字段");
                           continue;
                       }
                       Field field;
                       try {
                           field = targetClazz.getDeclaredField(propertyName);
                           JpaOracleComment anno = field.getAnnotation(JpaOracleComment.class);
                           if (Objects.nonNull(anno)) {
                               //数据库字段名
    String[] columns = persister.getPropertyColumnNames(propertyName);
                               String sql = "comment on column " +
                                       tableName +
                                       "." +
                                       columns[0] +
                                       " is " +
                                       "'" + anno.value() + "'";
                               this.jdbcTemplate.execute(sql);
                           }
                       } catch (NoSuchFieldException ex) {
                           ex.printStackTrace();
                       }
                   }
               }
           }
       }
    }

你可能感兴趣的:(springboot jpa oracle实体类中配置注解无法在数据库中生成注释的一种解决方式)