- 由 重写get/set 引发 JPA 的注解失效的问题
 - 我写了基类 BasicsIntEntity AuditIntID BaseAuditFieldsLocalDateTime
- 在 BasicsIntEntity 中重写了 AuditIntID BaseAuditFieldsLocalDateTime 的get ```java package com.databstech.cache.jpa.entity.mysql;
 
 
import com.databstech.cache.jpa.util.TnPageUtil; import com.databstech.utils.constant.entity.groups.AuditIntID; import com.databstech.utils.constant.entity.serializable.OvSerializable; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.domain.Page; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*; import java.util.ArrayList; import java.util.Iterator; import java.util.List;
/**
- @author tn
 - @version 1
 - @ClassName BaseDate
 - @description 公共实体INT 新建BaseDate,里面主要包含审计的公共字段,如新增人、新增时间、最后更新人、最后更新时间 *
 - @EntityListeners(AuditingEntityListener.class):声明实体监听器,用于实体修改时做处理
 - @MappedSuperclass:声明该类为实体父类,不会映射单独的表,而是把字段映射到子类表中
 - @date 2020-09-28 16:11
*/
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@DynamicUpdate //动态赋值
@DynamicInsert //动态插入
public class BasicsIntEntity
extends AuditIntID {  
@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(columnDefinition="int COMMENT '主键,自动生成'")@Overridepublic Integer getId() {return super.getId();}/*** 表示该字段为创建时间字段,在这个实体被insert的时候,会自动为其赋值*/@CreatedDate@Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期' ")@Overridepublic String getCreateTime() {return super.getCreateTime();}/*** 表示该字段为创建人, @CreatedBy 在这个实体被created的时候,会自动为其赋值*/@CreatedBy@Column(columnDefinition = "varchar(100) COMMENT '创建人'")@Overridepublic String getCreateBy() {return super.getCreateBy();}/*** 表示该字段为修改时间字段,@LastModifiedDate在这个实体被update的时候,会自动为其赋值*/@LastModifiedDate@Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期'")@Overridepublic String getUpdateTime() {return super.getUpdateTime();}/*** 表示该字段为修改人,@LastModifiedBy 在这个实体被update的时候,会自动为其赋值*/@LastModifiedBy@Column(columnDefinition = "varchar(100) COMMENT '更新人'")@Overridepublic String getUpdateBy() {return super.getUpdateBy();}/*** page* @param page* @param clazz* @param <T>* @param <S>* @return*/public static <T, S extends OvSerializable> TnPageUtil<List<T>> to(Page<S> page, Class<T> clazz) {if (page != null && !page.isEmpty()) {List<S> content = page.getContent();List<T> result = new ArrayList(content.size());Iterator var3 = content.iterator();while(var3.hasNext()) {OvSerializable abs = (OvSerializable)var3.next();result.add((T) abs.to(clazz));}return TnPageUtil.page(page.getNumber(),page.getSize(),page.getTotalPages(),page.getTotalElements(),result);} else {return new TnPageUtil();}}
}
2. 在最终使用的地方 继承 BasicsIntEntity ,结果发现本类中 @Column 出现了问题,生成不了注释```javapackage com.databstech.demo.standalone.jpa.bean;import com.databstech.cache.jpa.entity.mysql.BasicsIntEntity;import io.swagger.annotations.ApiModelProperty;import lombok.Getter;import lombok.Setter;import lombok.experimental.Accessors;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Table;/*** @author tn* @version 1* @ClassName JpaDemo* @description jpademo* @date 2020/10/2 0:47*/@Entity@Table(name ="jpa_demo",schema = "test")@org.hibernate.annotations.Table(appliesTo = "jpa_demo",comment = "jpademo")@Getter@Setter@Accessors(chain = true)public class JpaDemo extends BasicsIntEntity<JpaDemo> {//@Column无法生成 sql注释@ApiModelProperty("名字")@Column(columnDefinition = " varchar(100) not null comment '名字'" )private String name;@ApiModelProperty("性别")private String sex;// 只有这样写才能生成@Column(name = "sex",columnDefinition="varchar(100) default '男' COMMENT '字典名'")public String getSex() {return sex;}}
- 问题原因
- jpa 的 访问策略 问题 导致的
- 我在基类中 是把注解写在 get 上的 , 所以默认整个类都使用 get 的方式为准,详情↓
 
 - 当实体里的第一个jpa相关的注解出现在 字段 或者 get/set 方法上,就以第一次出现的方式为准!也就是说,一个实体里的注解既有用在field上面,又有用在 properties 上时,那么默认是一 field 为准,当出现在get/set方法上时就会失效!
 
 - jpa 的 访问策略 问题 导致的
 - 共存 
- 使用 @Access 指定实体类的访问策略 ! 下面是 该注解的源码 ```java @Target( { TYPE, METHOD, FIELD })//表示此注解可以运用在class上(那么这个时候就可以指定此实体的默认注解生效策略了),也可以用在方法上或者字段上(表示可以独立设置某一个字段或者方法的生效策略); @Retention(RUNTIME) public @interface Access { //指定是字段上面生效还是方法上面生效 AccessType value(); } public enum AccessType { FIELD, //字段 PROPERTY //属性 get/set }
 
 
1. 实例1. @Transient 防止二次序列化2. @Access 类上 跟 get 上都要加```java# 继承类package com.databstech.demo.standalone.jpa.bean;import com.databstech.cache.jpa.entity.mysql.BasicsIntEntity;import io.swagger.annotations.ApiModelProperty;import lombok.*;import lombok.experimental.Accessors;import org.hibernate.annotations.DynamicInsert;import org.hibernate.annotations.DynamicUpdate;import javax.persistence.*;/*** @author tn* @version 1* @ClassName JpaDemo* @description jpademo* @date 2020/10/2 0:47*/@Entity@Table(name ="jpa_demo",schema = "test")@org.hibernate.annotations.Table(appliesTo = "jpa_demo",comment = "jpademo")@Getter@Setter@Accessors(chain = true)@DynamicUpdate //动态赋值@DynamicInsert //动态插入@Access(AccessType.FIELD)@Builder(toBuilder = true)@NoArgsConstructor@AllArgsConstructorpublic class JpaDemo extends BasicsIntEntity<JpaDemo> {@Column(columnDefinition = " varchar(100) not null comment '名字'" )@ApiModelProperty("名字")private String name;@Column(name = "sex",columnDefinition="varchar(100) default '男' COMMENT '字典名'")@ApiModelProperty("性别")private String sex;// @Column(columnDefinition = " varchar(100) not null comment '名字'" )// public String getName() {// return name;// }// @Column(name = "sex",columnDefinition="varchar(100) default '男' COMMENT '字典名'")// public String getSex() {// return sex;// }}# 基类package com.databstech.cache.jpa.entity.mysql;import com.databstech.cache.jpa.util.TnPageUtil;import com.databstech.utils.constant.entity.groups.AuditIntID;import com.databstech.utils.constant.entity.serializable.OvSerializable;import org.hibernate.annotations.DynamicInsert;import org.hibernate.annotations.DynamicUpdate;import org.hibernate.annotations.SelectBeforeUpdate;import org.springframework.data.annotation.CreatedBy;import org.springframework.data.annotation.CreatedDate;import org.springframework.data.annotation.LastModifiedBy;import org.springframework.data.annotation.LastModifiedDate;import org.springframework.data.domain.Page;import org.springframework.data.jpa.domain.support.AuditingEntityListener;import javax.persistence.*;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/*** @author tn* @version 1* @ClassName BaseDate* @description 公共实体INT**新建BaseDate,里面主要包含审计的公共字段,如新增人、新增时间、最后更新人、最后更新时间** @EntityListeners(AuditingEntityListener.class):声明实体监听器,用于实体修改时做处理* @MappedSuperclass:声明该类为实体父类,不会映射单独的表,而是把字段映射到子类表中* @date 2020-09-28 16:11*/@EntityListeners(AuditingEntityListener.class)@MappedSuperclass@DynamicInsert //动态插入@DynamicUpdate //动态赋值@SelectBeforeUpdate@Access(AccessType.FIELD)public class BasicsIntEntity<T> extends AuditIntID<T> {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(columnDefinition="int COMMENT '主键,自动生成'")@Access(AccessType.PROPERTY)@Overridepublic Integer getId() {return super.getId();}/*** 表示该字段为创建时间字段,在这个实体被insert的时候,会自动为其赋值*/@CreatedDate@Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期' ")@Access(AccessType.PROPERTY)@Overridepublic String getCreateTime() {return super.getCreateTime();}/*** 表示该字段为创建人, @CreatedBy 在这个实体被created的时候,会自动为其赋值*/@CreatedBy@Column(columnDefinition = "varchar(100) COMMENT '创建人'")@Access(AccessType.PROPERTY)@Overridepublic String getCreateBy() {return super.getCreateBy();}/*** 表示该字段为修改时间字段,@LastModifiedDate在这个实体被update的时候,会自动为其赋值*/@LastModifiedDate@Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期'")@Access(AccessType.PROPERTY)@Overridepublic String getUpdateTime() {return super.getUpdateTime();}/*** 表示该字段为修改人,@LastModifiedBy 在这个实体被update的时候,会自动为其赋值*/@LastModifiedBy@Column(columnDefinition = "varchar(100) COMMENT '更新人'")@Access(AccessType.PROPERTY)@Overridepublic String getUpdateBy() {return super.getUpdateBy();}/*** page* @param page* @param clazz* @param <T>* @param <S>* @return*/public static <T, S extends OvSerializable> TnPageUtil<List<T>> to(Page<S> page, Class<T> clazz) {if (page != null && !page.isEmpty()) {List<S> content = page.getContent();List<T> result = new ArrayList(content.size());Iterator var3 = content.iterator();while(var3.hasNext()) {OvSerializable abs = (OvSerializable)var3.next();result.add((T) abs.to(clazz));}return TnPageUtil.page(page.getNumber(),page.getSize(),page.getTotalPages(),page.getTotalElements(),result);} else {return new TnPageUtil();}}}# 基类package com.databstech.utils.constant.entity.groups;import com.databstech.utils.constant.entity.audit.BaseAuditFieldsLocalDateTime;import io.swagger.annotations.ApiModelProperty;import javax.persistence.Transient;/*** @author tn* @ClassName IntAudit* @description int类型主键加审计字段* @date 2020-09-28 15:27*/public class AuditIntID<T> extends BaseAuditFieldsLocalDateTime<T> {@ApiModelProperty(value = "id")@Transientprivate Integer id;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}}
