无法反序列化异常 spring 引导数据 jpa
Could not deserialize exception spring boot data jpa
我正在使用 postgres 数据库并使用 spring data jpa 编写后端代码。
社区 table:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "community_table")
@Entity
public class CommunityTable {
@Id
@GeneratedValue
@Column(name = "community_id")
private Integer communityId;
@Column(name = "community_name", unique = true, nullable = false)
private String communityName;
@Column(name = "creation_date", nullable = false)
private Date creationDate;
@Column(name = "rules", columnDefinition = "text")
private String[] rules;
@ManyToOne
@JoinColumn(name = "creator_id", nullable = false)
private UserTable creatorId;
@ManyToOne
@JoinColumn(name = "current_owner", nullable = false)
private UserTable currentOwner;
}
用户table:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user_table")
@Entity
public class UserTable {
@Id
@GeneratedValue
@Column(name = "user_id", nullable = false)
private Integer userId;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Column(name = "username", nullable = false, unique = true)
private String username;
@Column(name = "join_date", nullable = false)
private Date joinDate;
@Column(name = "hashed_password", nullable = false)
private String hashedPassword;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "last_logged_in", nullable = false)
private Date lastLoggedIn;
@OneToMany(mappedBy = "creatorId")
private List<CommunityTable> creatorCommunity;
@OneToMany(mappedBy = "currentOwner")
private List<CommunityTable> ownerCommunity;
}
失败的控制器代码:
@GetMapping("/community")
public ResponseEntity getAllCommunities(){
try{
return new ResponseEntity<>(userService.getAllCommunities(), HttpStatus.OK);
}catch (Exception e){
log.error(e.toString());
return new ResponseEntity<String>("Unable to fetch all communities", HttpStatus.CONFLICT);
}
}
导致上述控制器方法失败的服务代码:
public List<CommunityTable> getAllCommunities() throws Exception{
try{
return communityTableRepository.findAll();
}catch (Exception e){
log.error(e.toString());
throw new Exception("Unable to fetch community due to: "+e.toString());
}
}
异常:
Hibernate: select communityt0_.community_id as communit1_0_, communityt0_.community_name as communit2_0_, communityt0_.creation_date as creation3_0_, communityt0_.creator_id as creator_5_0_, communityt0_.current_owner as current_6_0_, communityt0_.rules as rules4_0_ from community_table communityt0_
2022-01-05 22:34:14.989 ERROR 20231 --- [nio-8080-exec-1] c.e.redditbackend.service.UserService : org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
2022-01-05 22:34:14.990 ERROR 20231 --- [nio-8080-exec-1] c.e.r.controller.UserController : java.lang.Exception: Unable to fetch community due to: org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
不介意log.error。我已经用 @Log4j2 注释了服务和控制器 class,所以这不是这里的问题。由于某种原因,我无法获取社区列表-tables。
关于上述异常可能出现的任何想法。
这里的问题是由于:
@Column(name = "rules", columnDefinition = "text")
private String[] rules; // <-- column only holds a single string, not an array!
使用此列定义,DB 列不包含字符串数组,而是包含单个字符串,因此它只有在这样定义时才有效:
@Column(name = "rules", columnDefinition = "text")
private String rules; // <-- no array!
如果你想要多个(有序的)字符串,你可以切换到 @ElementCollection
:
@ElementCollection
@OrderColumn
@Column(columnDefinition = "text")
private List<String> strings; // (<-- not an array, but a list)
或者如果您确实需要一个数组 and/or,您希望将所有值存储在没有集合 table 的单个列中,您可以求助于 hibernate-types
:
implementation 'com.vladmihalcea:hibernate-types-55:2.14.0'
实体:
@TypeDef(
name = "string-array",
typeClass = StringArrayType.class
)
class MyEntity { // ...
@Type( type = "string-array" )
@Column(columnDefinition = "text[]") // <-- column matches entity attribute type
private String[] strings;
// ...
}
我正在使用 postgres 数据库并使用 spring data jpa 编写后端代码。
社区 table:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "community_table")
@Entity
public class CommunityTable {
@Id
@GeneratedValue
@Column(name = "community_id")
private Integer communityId;
@Column(name = "community_name", unique = true, nullable = false)
private String communityName;
@Column(name = "creation_date", nullable = false)
private Date creationDate;
@Column(name = "rules", columnDefinition = "text")
private String[] rules;
@ManyToOne
@JoinColumn(name = "creator_id", nullable = false)
private UserTable creatorId;
@ManyToOne
@JoinColumn(name = "current_owner", nullable = false)
private UserTable currentOwner;
}
用户table:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user_table")
@Entity
public class UserTable {
@Id
@GeneratedValue
@Column(name = "user_id", nullable = false)
private Integer userId;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Column(name = "username", nullable = false, unique = true)
private String username;
@Column(name = "join_date", nullable = false)
private Date joinDate;
@Column(name = "hashed_password", nullable = false)
private String hashedPassword;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "last_logged_in", nullable = false)
private Date lastLoggedIn;
@OneToMany(mappedBy = "creatorId")
private List<CommunityTable> creatorCommunity;
@OneToMany(mappedBy = "currentOwner")
private List<CommunityTable> ownerCommunity;
}
失败的控制器代码:
@GetMapping("/community")
public ResponseEntity getAllCommunities(){
try{
return new ResponseEntity<>(userService.getAllCommunities(), HttpStatus.OK);
}catch (Exception e){
log.error(e.toString());
return new ResponseEntity<String>("Unable to fetch all communities", HttpStatus.CONFLICT);
}
}
导致上述控制器方法失败的服务代码:
public List<CommunityTable> getAllCommunities() throws Exception{
try{
return communityTableRepository.findAll();
}catch (Exception e){
log.error(e.toString());
throw new Exception("Unable to fetch community due to: "+e.toString());
}
}
异常:
Hibernate: select communityt0_.community_id as communit1_0_, communityt0_.community_name as communit2_0_, communityt0_.creation_date as creation3_0_, communityt0_.creator_id as creator_5_0_, communityt0_.current_owner as current_6_0_, communityt0_.rules as rules4_0_ from community_table communityt0_
2022-01-05 22:34:14.989 ERROR 20231 --- [nio-8080-exec-1] c.e.redditbackend.service.UserService : org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
2022-01-05 22:34:14.990 ERROR 20231 --- [nio-8080-exec-1] c.e.r.controller.UserController : java.lang.Exception: Unable to fetch community due to: org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
不介意log.error。我已经用 @Log4j2 注释了服务和控制器 class,所以这不是这里的问题。由于某种原因,我无法获取社区列表-tables。
关于上述异常可能出现的任何想法。
这里的问题是由于:
@Column(name = "rules", columnDefinition = "text")
private String[] rules; // <-- column only holds a single string, not an array!
使用此列定义,DB 列不包含字符串数组,而是包含单个字符串,因此它只有在这样定义时才有效:
@Column(name = "rules", columnDefinition = "text")
private String rules; // <-- no array!
如果你想要多个(有序的)字符串,你可以切换到 @ElementCollection
:
@ElementCollection
@OrderColumn
@Column(columnDefinition = "text")
private List<String> strings; // (<-- not an array, but a list)
或者如果您确实需要一个数组 and/or,您希望将所有值存储在没有集合 table 的单个列中,您可以求助于 hibernate-types
:
implementation 'com.vladmihalcea:hibernate-types-55:2.14.0'
实体:
@TypeDef(
name = "string-array",
typeClass = StringArrayType.class
)
class MyEntity { // ...
@Type( type = "string-array" )
@Column(columnDefinition = "text[]") // <-- column matches entity attribute type
private String[] strings;
// ...
}