我有一个 JPA 实体“Users”,当我尝试通过 Gson 转换为 Json 时,出现 StackOverflowError
异常
@GetMapping("/users")
public ResponseEntity getUsers() {
List<Users> users = userRepository.findAll();
Gson gson = new GsonBuilder().setDateFormat("dd/MMM/yyyy HH:mm:ss").create();
String json = gson.toJson(users);
....
}
用户实体是
@Table(uniqueConstraints={@UniqueConstraint(columnNames = {"Email"})})
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class Users {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long Id;
@NotNull
private String Name;
@NotNull
private String Email;
@CreationTimestamp
@Temporal(value=TemporalType.TIMESTAMP)
private Date DateCreated;
@Transient
private String Password;
@ToString.Exclude
@JsonIgnore
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY)
private SecUser secuser;
@PrePersist
protected void onCreate() {
DateCreated = new Date();
}
@JsonIgnore
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
private final Set<Activity> activity = new HashSet<>();
}
我得到了异常(exception)...
java.lang.StackOverflowError: null
at java.base/sun.util.locale.provider.LocaleProviderAdapter.getAdapter(LocaleProviderAdapter.java:239) ~[na:na] java.base/java.text.DateFormatSymbols.getProviderInstance(DateFormatSymbols.java:368) ~[na:na]
at java.base/java.text.DateFormatSymbols.getInstance(DateFormatSymbols.java:346) ~[na:na]
at java.base/java.util.Calendar.getDisplayName(Calendar.java:2142) ~[na:na]
at java.base/java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1156) ~[na:na]
at java.base/java.text.SimpleDateFormat.format(SimpleDateFormat.java:997) ~[na:na]
at java.base/java.text.SimpleDateFormat.format(SimpleDateFormat.java:967) ~[na:na]
at java.base/java.text.DateFormat.format(DateFormat.java:374) ~[na:na]
at com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:96) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:46) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.TypeAdapters$26$1.write(TypeAdapters.java:587) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.TypeAdapters$26$1.write(TypeAdapters.java:580) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245) ~[gson-2.8.5.jar:na]
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1018) ~[gson-2.8.5.jar:na]
我已经使用非实体对象成功地实现了此策略。我怎样才能让它发挥作用?
最佳答案
问题在于序列化双向一对一和一对多关系。 (我猜它是双向的,因为它们是mappedBy =“user”
)。
这是因为@JsonIgnore
是来自jackson的注释,而不是来自gson的注释。要从 gson 中的序列化中排除字段,您必须采取其他方式 - 使用 @Expose
注释每个其他字段,以便未注释的字段(在您的情况下 - secuser
code> 和 activity
)不会被序列化。
其他解决方案是使所有不可序列化字段transient
,但由于它是一个@Entity
,因此这无法完成任务。如果首先映射到 DTO,它就会起作用。尽管有很多附加注释,第一个解决方案似乎更简单。
有关 gson 中排除的更多信息,您可以找到 here .
最后一个可能的解决方案 - 使用 jackson 而不是 gson。
关于java - 从 JPA 实体创建 Gson 对象抛出StackOverflowError 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57667637/