ไม่มีเมธอด CrudRepository # findOne


101

ฉันใช้ Spring 5 ในโครงการของฉัน CrudRepository#findOneจนถึงวันนี้มีวิธีการที่มีอยู่

แต่หลังจากดาวน์โหลด snapshot ล่าสุดมันก็หายไปทันที! มีการอ้างอิงว่าวิธีนี้ไม่สามารถใช้ได้ในขณะนี้หรือไม่?

รายการพึ่งพาของฉัน:

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'


repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}    

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'

    runtime 'com.h2database:h2:1.4.194'
}

อัพเดท:

ดูเหมือนว่าวิธีนี้จะถูกแทนที่ด้วย CrudRepository#findById

คำตอบ:


153

โปรดดูDATACMNS-944ซึ่งเชื่อมโยงกับคอมมิตนี้ซึ่งมีการเปลี่ยนชื่อดังต่อไปนี้

╔═════════════════════╦═══════════════════════╗
║      Old name       ║       New name        ║
╠═════════════════════╬═══════════════════════╣
║ findOne(…)          ║ findById(…)           ║
╠═════════════════════╬═══════════════════════╣
║ save(Iterable)      ║ saveAll(Iterable)     ║
╠═════════════════════╬═══════════════════════╣
║ findAll(Iterable)   ║ findAllById(…)        ║
╠═════════════════════╬═══════════════════════╣
║ delete(ID)          ║ deleteById(ID)        ║
╠═════════════════════╬═══════════════════════╣
║ delete(Iterable)    ║ deleteAll(Iterable)   ║
╠═════════════════════╬═══════════════════════╣
║ exists()            ║ existsById(…)         ║
╚═════════════════════╩═══════════════════════╝

1
มีคู่มือการย้ายข้อมูลที่ฉันพลาดไปหรือไม่หรือบรรทัดที่คลุมเครือจากบันทึกประจำรุ่นทั้งหมดนี้ในแง่ของการประกาศมีหรือไม่ "DATAJPA-1104 - ปรับให้เข้ากับการเปลี่ยนแปลง API ในอินเทอร์เฟซที่เก็บ" คุณค้นพบได้อย่างไร :-)
Christian

2
ไม่แน่ใจว่านี่เป็นคู่มือการย้ายข้อมูลหรือไม่ แต่คุณสามารถดูข้อมูลอ้างอิงได้ในวิกิของ Kay release train wiki ( github.com/spring-projects/spring-data-commons/wiki/… ) รวมถึงการเปลี่ยนแปลง Spring Data Commons ( docs .spring.io / spring-data / commons / docs / current / changelog.txt )
Sean Carroll

104

โปรดทราบว่าfindByIdไม่ได้เป็นที่แน่นอนสำหรับการทดแทนfindOneก็ส่งกลับแทนOptionalnull

การไม่คุ้นเคยกับสิ่งใหม่ ๆ ของ java ฉันใช้เวลาสักครู่ในการคิดออก แต่สิ่งนี้ทำให้findByIdพฤติกรรมกลายfindOneเป็น:

return rep.findById(id).orElse(null);

1
ไม่คิดที่ดีที่สุด: รหัสของคุณจะยังคงทำงาน แต่คุณไม่ได้ใช้ API ที่คุณควร Optionalถูกเพิ่มเพื่อล้างรหัสจากการnullตรวจสอบทั้งหมด เพียงแค่เปลี่ยนวิธีการส่งคืนของคุณและใช้Optionalเหมือนลูกเสือที่ดีควร
GabiM

5
@GabiM นี่จะดีมากถ้าคุณสามารถควบคุมวิธีการทั้งหมดที่อยู่ด้านล่างได้ แม้ว่าคุณจะมีการควบคุมทุกอย่างของดาวน์สตรีมและโปรเจ็กต์ของคุณไม่ใช่การพึ่งพาสำหรับโปรเจ็กต์ของบุคคลที่สามอื่น ๆ หากเมธอดรหัสดาวน์สตรีมเป็นโมฆะ (เช่นเดียวกับสร้างหากไม่มีอยู่หรือใช้ตรรกะบางอย่างหากขาดหายไป) แสดงว่าคุณมี เพื่อแก้ไขเช่นกัน
zeusalmighty

ในการอ้างอิงถึงลิงก์จาก @GabiM ฉันแค่อยากจะชี้ให้เห็นว่าแม้ลิงก์นั้นจะระบุว่า "สิ่งสำคัญคือต้องทราบว่าเจตนาของคลาสตัวเลือกไม่ได้แทนที่การอ้างอิงที่ว่างเปล่าทุกรายการ"
Scott Carlson

32

เรามีการใช้findOne()วิธีการเดิม ๆ มากมายหลายร้อยแบบ แทนที่จะดำเนินการกับ refactor แมมมอ ธ เราลงเอยด้วยการสร้างอินเทอร์เฟซตัวกลางต่อไปนี้และให้ที่เก็บของเราขยายแทนการขยายJpaRepositoryโดยตรง

@NoRepositoryBean
public interface BaseJpaRepository<T, ID> extends JpaRepository<T, ID> { 
    default T findOne(ID id) { 
        return (T) findById(id).orElse(null); 
    } 
} 

ทางออกที่ดีสำหรับฉัน ไม่จำเป็นต้องหล่อ return findById(id).orElse(null);พอเพียง
Ken007

เห็นด้วยอย่างสิ้นเชิง. บันทึกการเปลี่ยนแปลงหลายร้อยบรรทัดให้ฉัน
Scott Carlson

7

การเปลี่ยนแปลงในทางปฏิบัติ

วิธีเก่า:

Entity aThing = repository.findOne(1L);

วิธีการใหม่:

Optional<Entity> aThing = repository.findById(1L);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.