A solution to the problem that configuration annotation in springboot JPA Oracle entity class cannot generate annotation in database

Time:2021-5-3

demand

aboutoracleDatabase,jpaOfEntityEven if comments are configured@Column (columndefinition ='column comment '), unable to generate comments for columns in the database tier

Solution

User defined annotation, configured inEntityClass, when the project is initialized, theEntityManagerGet all the entity classes, traverse whether the annotation is configured in the entity class, if so, dynamically spliceDDLStatement and execute

  • Custom annotation:

    import java.lang.annotation.*;
    /**
    *Description: * to solve the problem that the field comment cannot be added in the process of creating a table based on the entity class
    * @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<String, EntityPersister> persisterMap = sessionFactory.getMetamodel().entityPersisters();
           if(Objects.nonNull(persisterMap) && persisterMap.keySet().size() > 0){
               for(Map.Entry<String, EntityPersister> entry: persisterMap.entrySet()){
                   Class<?> targetClazz = entry.getValue().getMappedClass();
                   SingleTableEntityPersister persister = (SingleTableEntityPersister)entry.getValue();
                   //Data table name
    String tableName = persister.getTableName();
                   //Add a comment for the table
    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()) {
                       //Property name
    String propertyName = attributeDefinition.getName();
                       if (propertyName.equalsIgnoreCase("_identifierMapper")) {
                           Log. Warn ("trying to generate annotation for entity class: + targetclazz. Getsimplename() +", found union primary key, unable to process temporarily, ignored corresponding field ");
                           continue;
                       }
                       Field field;
                       try {
                           field = targetClazz.getDeclaredField(propertyName);
                           JpaOracleComment anno = field.getAnnotation(JpaOracleComment.class);
                           if (Objects.nonNull(anno)) {
                               //Database field name
    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();
                       }
                   }
               }
           }
       }
    }