Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用JPA持久化LocalDate?_Java_Spring_Spring Boot_Java 8_Spring Data Jpa - Fatal编程技术网

Java 如何使用JPA持久化LocalDate?

Java 如何使用JPA持久化LocalDate?,java,spring,spring-boot,java-8,spring-data-jpa,Java,Spring,Spring Boot,Java 8,Spring Data Jpa,我想将没有时间的日期存储到我的数据库中。因此,我选择使用LocalDatetype 如中所述,我使用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

我想将没有时间的日期存储到我的数据库中。因此,我选择使用
LocalDate
type

如中所述,我使用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]
代码

转换器

“主要”

谢谢你的帮助

编辑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"]>
HttpHeaders=newhttpheaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity=新的HttpEntity(this.toJsonString(myObject),头文件);
System.out.println(entity.toString());
// 

Hibernate 5支持java 8,因此您可以将其添加到pom.xml中:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>5.1.0.Final</version>
</dependency>

org.hibernate
hibernate-java8
5.1.0.1最终版本

这为您提供了现成的
LocalDate
LocalDateTime
映射。

jpa2.2支持
LocalDate
,因此不需要转换器

Hibernate从5.3版开始也支持它


查看了解更多详细信息。

我认为您可以编写自己的转换器,请检查答案:

对于JPA 2.2,您不再需要使用转换器,它添加了对以下java.time类型映射的支持:

java.time.LocalDate
java.time.LocalTime
java.time.LocalDateTime
java.time.OffsetTime
java.time.OffsetDateTime

JPA2.2增加了对映射Java8日期/时间API的支持,如
LocalDate
LocalTime
LocalDateTime
OffsetDateTime
OffsetTime

那么,假设我们有以下实体:

@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
}
请注意,
subscribedOn
属性是一个
LocalDate
Java对象

持久化
用户帐户时

UserAccount user = new UserAccount()
    .setId(1L)
    .setFirstName("Vlad")
    .setLastName("Mihalcea")
    .setSubscribedOn(
        LocalDate.of(
            2013, 9, 29
        )
    );

entityManager.persist(user);
Hibernate生成正确的SQL INSERT语句:

INSERT INTO user_account (
    first_name, 
    last_name, 
    subscribed_on, 
    id
) 
VALUES (
    'Vlad', 
    'Mihalcea', 
    '2013-09-29', 
    1
)
在获取
UserAccount
实体时,我们可以看到
LocalDate
正确地从数据库中获取:

UserAccount userAccount = entityManager.find(
    UserAccount.class, 1L
);

assertEquals(
    LocalDate.of(
        2013, 9, 29
    ),
    userAccount.getSubscribedOn()
);

所以JSON中有一个错误,它不是JPA。即使是JPA,您也需要提到您使用的JPA提供商,以及您认为本地日期处理不当的地方。您的调试是什么say@BillyFrost我编辑了我的问题。我在
JSON
中打印
myObject
。该格式不是我的格式化程序中指定的格式…它无法隔离问题所在。您在JPA中的问题是没有将数据持久化到数据库中,还是没有从数据库中检索数据。。。。或者只是将Java对象转换成JSON?????如果问题在持久性中,那么定义使用什么SQL来持久化,以及您认为该SQL的问题在哪里。。。“坚持”不涉及POST/PUT。。。它涉及JPA em.persist。因此,我不明白的是为什么
sysout()
中的格式不是
yyyy-MM-dd
。因为如果我执行
sysout(myObject.getStartdate())
的话,结果是日期的格式是
yyyy-MM-dd
好的,那么与JPA无关。
LocalDate
.toString()方法有自己的输出格式,由JAVADOCS定义,这与“问题”有什么关系?如果我有LocalDate可选项,并将其发送为null,oracle将返回:expected date get binary,如果我使用java.util.date,则不会发生这种情况。我如何用jpa解决这个问题?
@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
}
UserAccount user = new UserAccount()
    .setId(1L)
    .setFirstName("Vlad")
    .setLastName("Mihalcea")
    .setSubscribedOn(
        LocalDate.of(
            2013, 9, 29
        )
    );

entityManager.persist(user);
INSERT INTO user_account (
    first_name, 
    last_name, 
    subscribed_on, 
    id
) 
VALUES (
    'Vlad', 
    'Mihalcea', 
    '2013-09-29', 
    1
)
UserAccount userAccount = entityManager.find(
    UserAccount.class, 1L
);

assertEquals(
    LocalDate.of(
        2013, 9, 29
    ),
    userAccount.getSubscribedOn()
);