2016-11-15 4 views
1

私はいくつかのJPAリポジトリを持つSpringブートアプリケーションを持っています。 Iリポジトリインターフェースの一内部以下の方法定義:かなり明らかSpringのデータリポジトリ:orderByの「find」メソッドが間違った順序を取得する

public List<Post> findAllByOrderByPublishedOnDesc(); 

を、IはpublishOn DESCによってソートされたすべてのPostのリストをretriveたいです。不思議なことに、2つ以上の投稿のLocalDateTimeクラスの分だけ異なるpublishedOnの値があると、私は間違って注文を受け取ります(下記のコメントを参照)。 私は間違っていますか?

コード例を示します。試験は、H2のデータベースで実行される:

エンティティ:

@Entity 
    public class Post 
    { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     Long id; 

     @Column(unique = true, nullable = false) 
     String sourceUrl; 

     @Column 
     String title; 

     @Column 
     LocalDateTime publishedOn; 

     @LastModifiedDate 
     LocalDateTime editedOn; 

     @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
     Text text; 
    } 

レポジトリ:

public interface PostRepository extends JpaRepository<Post, Long> 
    { 
     public Post findBySourceUrl(String sourceUrl); 
     public List<Post> findAllByOrderByPublishedOnDesc(); 
    } 

試験:

public class OrderByJPATest 
    { 
    @Autowired 
    PostRepository postRepo; 

    public OrderByJPATest() 
    { 
    } 

    @Test 
    public void testOrderByDays() 
    { 
      // First try: older by 1 day 
      Post newer = insertTestEntity("newer", LocalDateTime.of(2016, 11, 13, 0, 0)); 
      Post older = insertTestEntity("older", LocalDateTime.of(2016, 11, 12, 0, 0)); 

      List<Post> ordered = postRepo.findAllByOrderByPublishedOnDesc(); 

      ordered.stream().forEach((post) -> log.info("{} => {}", post.getSourceUrl(), post.getPublishedOn())); 

      /* 
      output: 
      newer => 2016-11-13T00:00 
      older => 2016-11-12T00:00 
      */ 

      assertTrue(ordered.get(0).getPublishedOn() 
        .isAfter(ordered.get(1).getPublishedOn())); 

      postRepo.deleteAll(); 
      postRepo.flush(); 

      // Second try: older by 1 minute 
      newer = insertTestEntity("newerBy1Min", LocalDateTime.of(2016, 11, 13, 01, 02)); 
      older = insertTestEntity("olderBy1Min", LocalDateTime.of(2016, 11, 13, 01, 01)); 

      ordered = postRepo.findAllByOrderByPublishedOnDesc(); 

      ordered.stream().forEach((post) -> log.info("{} => {}", post.getSourceUrl(), post.getPublishedOn())); 

      /* 
      output: 
      olderBy1Min => 2016-11-13T01:01 
      newerBy1Min => 2016-11-13T01:02 
      */ 

      // this assert fails! 
      assertTrue(ordered.get(0).getPublishedOn() 
        .isAfter(ordered.get(1).getPublishedOn())); 
    } 

    private Post insertTestEntity(String url, LocalDateTime publishDate) 
    { 
      Text text = new Text(); 
      text.setValue("Testing..."); 
      Post post = new Post(); 
      post.setPublishedOn(publishDate); 
      post.setSourceUrl(url); 
      post.setText(text); 

      return postRepo.save(post); 
    } 
    } 

POM(依存関係):

<dependencies> 

     <dependency> 
      <groupId>com.atlassian.commonmark</groupId> 
      <artifactId>commonmark</artifactId> 
      <version>0.6.0</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-io</groupId> 
      <artifactId>commons-io</artifactId> 
      <version>2.4</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-lang</groupId> 
      <artifactId>commons-lang</artifactId> 
      <version>2.6</version> 
     </dependency> 
     <!--Additional dependencies -end--> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-rest</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.projectlombok</groupId> 
      <artifactId>lombok</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-security</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-thymeleaf</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-logging</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.thymeleaf.extras</groupId> 
      <artifactId>thymeleaf-extras-java8time</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>com.h2database</groupId> 
      <artifactId>h2</artifactId> 
      <scope>runtime</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-test</artifactId> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 
+1

java.util.Dateへのマッピングを試したことがあり、その動作が変わるかどうかを確認しましたか? – JustinKSU

+0

@ neil-stocktontonどのようなバージョンのSpring Bootを使用していますか?依存関係のバージョンをオーバーライドした場合はお知らせください。 –

+0

@ punkrocker27ka私は1.4.1.RELEASEを使用していますが、私のPOMには除外や上書きはありません –

答えて

1

JPAは、デフォルトでJavaのLocalDateTimeDateTimeまたはTimestampの代わりにBLOBにマップします。

データベースは、BLOBで日付/時刻ソートを実行する方法を理解していません。

  1. 適切なデータ型(@ColumnアノテーションまたはSQLスクリプトを使用)を使用してスキーマを作成していることを確認してください。
  2. 上記の手順を実行した後、プロジェクト

hibernate-java8依存関係を追加し、正しい順序で行われます。

+0

私は 'hibernate-java8'を持っていますが、それでも動作しません。たぶん私はあなたの答えの最初の点を忘れています。列の適切な定義は何ですか?あなたは例を見せてもらえますか?どうもありがとうございました。 –

+0

@EvilToad私はJavaのLocalDateTimeのSQL内でTIMESTAMPデータ型を使用しました。この完全な実際の例を参照してください:https://github.com/kanderson450/stackoverflow-q40616629 –

+1

それを釘付け!今は期待どおりに動作します。努力のために非常に多くの非常にありがとう。 –

関連する問題