Roy*_*yce 6 java spring jpa spring-data-jpa spring-boot
我想没有时间将日期存储到数据库中。所以我选择使用LocalDate类型。
如此处所述https://thoughts-on-java.org/persist-localdate-localdatetime-jpa/我使用转换器将转换LocalDate为Date。
但是,当我要保留我的实体(使用POST和PUT请求)时,会遇到一些麻烦。
错误
2019-02-23 11:26:30.254 WARN 2720 --- [-auto-1-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string.
at [Source: (PushbackInputStream); line: 1, column: 104] (through reference chain: ...entity.MyObject["startdate"])]
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.springframework.http.ResponseEntity]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.http.ResponseEntity` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
Run Code Online (Sandbox Code Playgroud)
码
转换器
package ...entity;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.time.LocalDate;
import java.sql.Date;
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
Run Code Online (Sandbox Code Playgroud)
实体
package ...entity;
import org.hibernate.annotations.ColumnDefault;
import javax.persistence.*;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
@Entity
public class MyObject {
@Id
private String id;
private LocalDate startdate;
private LocalDate enddate;
public MyObject() {}
public MyObject(LocalDate enddate) {
this.startdate = LocalDate.now();
this.enddate = enddate;
}
...
}
Run Code Online (Sandbox Code Playgroud)
“主要”
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
MyObject myobject = new MyObject(LocalDate.parse("2019-03-01", formatter));
Run Code Online (Sandbox Code Playgroud)
感谢帮助。
编辑1:MyObject的打印
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(this.toJsonString(myObject), headers);
System.out.println(entity.toString());
// <{"id":"ba6649e4-6e65-4f54-8f1a-f8fc7143b05a","startdate":{"year":2019,"month":"FEBRUARY","dayOfMonth":23,"dayOfWeek":"SATURDAY","era":"CE","dayOfYear":54,"leapYear":false,"monthValue":2,"chronology":{"id":"ISO","calendarType":"iso8601"}},"enddate":{"year":2019,"month":"MARCH","dayOfMonth":1,"dayOfWeek":"FRIDAY","era":"CE","dayOfYear":60,"leapYear":false,"monthValue":3,"chronology":{"id":"ISO","calendarType":"iso8601"}}},[Content-Type:"application/json"]>
Run Code Online (Sandbox Code Playgroud)
小智 11
使用 JPA 2.2,您不再需要使用转换器,它添加了对以下 java.time 类型映射的支持:
java.time.LocalDate
java.time.LocalTime
java.time.LocalDateTime
java.time.OffsetTime
java.time.OffsetDateTime
Run Code Online (Sandbox Code Playgroud)
@Column(columnDefinition = "DATE")
private LocalDate date;
@Column(columnDefinition = "TIMESTAMP")
private LocalDateTime dateTime;
@Column(columnDefinition = "TIME")
private LocalTime localTime;
Run Code Online (Sandbox Code Playgroud)
使用JPA 2.2,不需要转换器。Hibernate从5.3版本开始支持它。 https://vladmihalcea.com/whats-new-in-jpa-2-2-java-8-date-and-time-types/
JPA 2.2 添加了对映射 Java 8 日期/时间 API 的支持,例如LocalDate、、或。LocalTimeLocalDateTimeOffsetDateTimeOffsetTime
因此,假设我们有以下实体:
@Entity(name = "UserAccount")
@Table(name = "user_account")
public class UserAccount {
@Id
private Long id;
@Column(name = "first_name", length = 50)
private String firstName;
@Column(name = "last_name", length = 50)
private String lastName;
@Column(name = "subscribed_on")
private LocalDate subscribedOn;
//Getters and setters omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
请注意,该subscribedOn属性是一个LocalDateJava 对象。
当坚持UserAccount:
UserAccount user = new UserAccount()
.setId(1L)
.setFirstName("Vlad")
.setLastName("Mihalcea")
.setSubscribedOn(
LocalDate.of(
2013, 9, 29
)
);
entityManager.persist(user);
Run Code Online (Sandbox Code Playgroud)
Hibernate 生成正确的 SQL INSERT 语句:
INSERT INTO user_account (
first_name,
last_name,
subscribed_on,
id
)
VALUES (
'Vlad',
'Mihalcea',
'2013-09-29',
1
)
Run Code Online (Sandbox Code Playgroud)
当获取UserAccount实体时,我们可以看到已经LocalDate从数据库中正确获取了实体:
UserAccount userAccount = entityManager.find(
UserAccount.class, 1L
);
assertEquals(
LocalDate.of(
2013, 9, 29
),
userAccount.getSubscribedOn()
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2254 次 |
| 最近记录: |