實體類有繼承父類,但父類沒有單獨標明注解
異常表現
1 Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.xxx.ProjectDTO
解決方式
- 可以看到ProjectDTO有繼承一個BaseDTO,那么在父類中肯定存在某些字段需要與數據庫表字段對應
- 因此類父需要使用
@MappedSuperclass
標注為映射的父類,即可解決上述問題@Entity @Table(name = "al_project") public class ProjectDTO extends BaseDTO { ... } @MappedSuperclass public class BaseDTO { ... }
自定義接口實現了JpaRepository,但沒有單獨標明注解
異常表現
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseJpaRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object ... Caused by: java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object
解決方式
- 上述報錯中提到BaseJpaRepository創建失敗,其實是因為該接口繼承JpaRepository,繼承CrudRepository同理
- 導致SpringBoot把該類認為是Jpa的某一個存儲庫,所以需要添加
@NoRepositoryBean
告知SpringBoot該類不是一個存儲庫
@NoRepositoryBean public interface BaseJpaRepository<T, ID> extends JpaRepository<T, ID> { ... }
實體類創建后沒有單獨標明注解@Entity
異常表現
- 需要注意的是這個錯誤可能不完全以下內容
*************************** APPLICATION FAILED TO START *************************** ... The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) ...
解決方式
- 檢查所有的實體類,並添加全部上
@Entity
注解 - 需要注意的是以下實體類ConfigDTO繼承了BaseDTO,而BaseDTO作為父類不應該使用
@Entity
注解 - 而使用應該問題上述提到中的
@MappedSuperclass
標明的英文映射父類
@Entity @Table(name = "al_config") public class ConfigDTO extends BaseDTO { ... }
實體類中的某個字段是一個對象,卻錯誤的使用了@Column注解
異常表現
Caused by: org.hibernate.MappingException: Could not determine type for: com.asing1elife.teamnote.dto.ProjectGroupDTO, at table: al_project, for columns: [org.hibernate.mapping.Column(project_group)]
解決方式
- 以下類中ProjectGroupDTO應該是一個對象,所以根據應該具體映射情況決定的英文使用
@ManyToOne
還是@OneToMay
,或其他對象映射規則
@Entity @Table(name = "al_project") public class ProjectDTO extends BaseDTO { @Column private ProjectGroupDTO projectGroup; }
實體類ID使用了錯誤的生成規則
異常表現
java.sql.SQLSyntaxErrorException: Table 'asl_station.hibernate_sequence' doesn't exist
public class BaseDTO { @Id @GeneratedValue private Long id = 0L; }
解決方式
- 上述類中在ID上通過
@GeneratedValue
直接指定生成規則,就會拋出上述異常 - 因為默認的生成規則是
GeneratedType.AUTO
- 而我們在創建表時,通常使用的ID自增規則都是
auto_increment
,這對應的應該是GenerationType.IDENTITY
- 所以應該使用如下方式指定ID的自增規則
public class BaseDTO { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id = 0L; }
修改JPA的字段命名規則為駝峰式
異常表現
- 在實體類和數據庫中對應的字段都是createTime,但是JPA在連接對應表時卻拋出如下錯誤
- 因為JPA默認的字段映射規則是下划線風格
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'create_time' in 'field list'
@Column private Date createTime = DateUtil.getSysDate();
解決方式
- 在配置文件中指定JPA的字段映射規則為駝峰式即可
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
獲取單個實體類JSON轉換異常
異常表現
- Hibernate的獲取單個實體類數據后,為會每個實體類添加一個
hibernateLazyInitializer
屬性,改屬性在進行JSON轉換時拋出異常
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.asing1elife.teamnote.core.bean.ResponseData["data"]->com.asing1elife.teamnote.dto.OrganizationDTO$HibernateProxy$f3Tr4vBI["hibernateLazyInitializer"])
解決方式一
- 在實體類頂部添加
@JsonIgnoreProperties("hibernateLazyInitializer")
,確保數據轉換時會過濾掉休眠生成的屬性@JsonIgnoreProperties("hibernateLazyInitializer") public class BaseDTO { ... }
解決方式二
- 上述根據報錯
disable SerializationFeature.FAIL_ON_EMPTY_BEANS
可以嘗試將JSON轉換時的以下屬性設置為false
spring: jackson: serialization: fail-on-empty-beans: false
前端數據傳遞到后端過程中,反序列失敗
異常表現
- 傑克遜反序列化時需要無參構造函數,因為數據對應的實體類某個對象屬性沒有無參構造函數,就會拋出以下異常
(although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
解決方式
- 檢查實體類自身以及所有對象屬性,為每個對象添加對應的無參構造函數即可解決
- 自參考博客園