Ví dụ về dữ liệu mùa xuân mongodb enum

Tôi muốn mã không ném ngoại lệ khi mã java tải giá trị enum từ mongo không tồn tại trong mã enum

Ví dụ

java.lang.IllegalArgumentException: No enum constant fr.myapp.type.OrderOptionEnum.TELEPHONE
at java.lang.Enum.valueOf(Enum.java:238)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:819)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:909)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1184)

Bởi vì ĐIỆN THOẠI không tồn tại trong Order Option Enum

Tôi chỉ muốn mã trả về giá trị null

Bất kỳ ý tưởng ?

Trân trọng

Giải pháp tốt nhất

bạn có thể thêm triển khai trình chuyển đổi tùy chỉnh Converter ở đó bạn triển khai logic chuyển đổi của riêng mình từ chuỗi sang enum của bạn

một cái gì đó như thế này

public class OrderOptionEnumMongoConverter implements Converter {

    @Override
    public OrderOptionEnum convert(String source) {

        for (OrderOptionEnum OrderOptionEnum : OrderOptionEnum.values()) {
            if (OrderOptionEnum.name().equals(source))
                return OrderOptionEnum;
        }

        return null;
    }
}

Để ý. Trình chuyển đổi này sẽ cố gắng chuyển đổi từng chuỗi trong mongo sang enum của bạn, do đó có thể dẫn đến các chuyển đổi không mong muốn, vì vậy hãy đảm bảo bạn chỉ thực hiện việc này khi cần. bạn có thể thêm @ReadingConverter nếu bạn chỉ muốn chuyển đổi này khi đọc từ mongo

Giải pháp liên quan

Eclipse – Cách giải quyết “Thực thi plugin không nằm trong cấu hình vòng đời” cho Bản dựng Maven dữ liệu mùa xuân

In my case of a similar problem, instead of using Andrew's suggestion for the fix, it worked simply after I introduced tag to the pom.xml in question. Looks like that error is due to a missing tag. So, in order to avoid the exceptions in Eclipse, one needs to simply enclose all the plugin tags inside a tag, like so:


    
        
             .. 
             .. 
                  ....
        
    

Khi cấu trúc này được đặt đúng chỗ, lỗi sẽ biến mất

Java – Đâu là sự khác biệt giữa các chú thích @Component, @Repository & @Service trong Spring

Từ

Chú thích @Repository là điểm đánh dấu cho bất kỳ lớp nào đáp ứng vai trò hoặc khuôn mẫu của kho lưu trữ (còn được gọi là Đối tượng truy cập dữ liệu hoặc DAO). Trong số các cách sử dụng của điểm đánh dấu này là bản dịch tự động của các ngoại lệ, như được mô tả trong

Spring cung cấp thêm các chú thích khuôn mẫu. @Component, @Service@Controller. @Component là khuôn mẫu chung cho mọi thành phần do Spring quản lý. @Repository, @Service@Controller là các chuyên biệt hóa của @Component cho các trường hợp sử dụng cụ thể hơn (tương ứng trong các lớp kiên trì, dịch vụ và trình bày). Do đó, bạn có thể chú thích các lớp thành phần của mình bằng @Component, nhưng thay vào đó, bằng cách chú thích chúng bằng @Repository, @Service hoặc @Controller, các lớp của bạn phù hợp hơn để xử lý bằng các công cụ hoặc liên kết với các khía cạnh

Ví dụ: các chú thích khuôn mẫu này tạo ra các mục tiêu lý tưởng cho các điểm cắt. @Repository, @Service@Controller cũng có thể mang ngữ nghĩa bổ sung trong các bản phát hành Spring Framework trong tương lai. Do đó, nếu bạn đang lựa chọn giữa việc sử dụng @Component hoặc @Service cho lớp dịch vụ của mình, thì rõ ràng @Service là lựa chọn tốt hơn. Tương tự, như đã nêu trước đó, @Repository đã được hỗ trợ làm điểm đánh dấu cho bản dịch ngoại lệ tự động trong lớp kiên trì của bạn

Chú thích Ý nghĩa@Componentkhuôn mẫu chung cho bất kỳ thành phần nào do Spring quản lý@Repositorykiểu khuôn mẫu cho lớp kiên trì@Servicekiểu khuôn mẫu cho lớp dịch vụ@Controllerkiểu khuôn mẫu cho lớp trình bày (spring-mvc)

Trong JPA phiên bản 2. 0 trở xuống, không có cách nào thuận tiện để ánh xạ các giá trị Enum vào cột cơ sở dữ liệu. Mỗi tùy chọn đều có những hạn chế và nhược điểm của nó. Những vấn đề này có thể tránh được bằng cách sử dụng JPA 2. 1 tính năng

Trong hướng dẫn này, chúng ta sẽ xem xét các khả năng khác nhau mà chúng ta có để duy trì enum trong cơ sở dữ liệu bằng cách sử dụng JPA. Chúng tôi cũng sẽ mô tả những ưu điểm và nhược điểm của chúng cũng như cung cấp các ví dụ mã đơn giản

2. Sử dụng Chú thích @Enumerated

Tùy chọn phổ biến nhất để ánh xạ giá trị enum đến và từ biểu diễn cơ sở dữ liệu của nó trong JPA trước 2. 1 là sử dụng chú thích @Enumerated. Bằng cách này, chúng ta có thể hướng dẫn một nhà cung cấp JPA chuyển đổi một enum thành giá trị chuỗi hoặc thứ tự của nó

Chúng ta sẽ khám phá cả hai tùy chọn trong phần này

Nhưng trước tiên hãy tạo một @Entity đơn giản mà chúng ta sẽ sử dụng trong suốt hướng dẫn này

@Entity
public class Article {
    @Id
    private int id;

    private String title;

    // standard constructors, getters and setters
}

2. 1. Ánh xạ giá trị thứ tự

Nếu chúng ta đặt @Enumerated(EnumType. ORDINAL) trên trường enum, JPA sẽ sử dụng giá trị khi duy trì một thực thể nhất định trong cơ sở dữ liệu

Hãy giới thiệu enum đầu tiên

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}

Tiếp theo, hãy thêm nó vào lớp Article và chú thích nó bằng @Enumerated(EnumType. THÔNG THƯỜNG)

@Entity
public class Article {
    @Id
    private int id;

    private String title;

    @Enumerated(EnumType.ORDINAL)
    private Status status;
}

Bây giờ khi duy trì một thực thể Article

Article article = new Article();
article.setId(1);
article.setTitle("ordinal title");
article.setStatus(Status.OPEN);

JPA sẽ kích hoạt câu lệnh SQL sau

insert 
into
    Article
    (status, title, id) 
values
    (?, ?, ?)
binding parameter [1] as [INTEGER] - [0]
binding parameter [2] as [VARCHAR] - [ordinal title]
binding parameter [3] as [INTEGER] - [1]

Một vấn đề phát sinh với loại ánh xạ này khi chúng ta cần sửa đổi enum của mình. Nếu chúng ta thêm một giá trị mới vào giữa hoặc sắp xếp lại thứ tự của enum, chúng ta sẽ phá vỡ mô hình dữ liệu hiện có

Những vấn đề như vậy có thể khó phát hiện cũng như khó khắc phục vì chúng tôi sẽ phải cập nhật tất cả các bản ghi cơ sở dữ liệu

2. 2. Ánh xạ giá trị chuỗi

Tương tự, JPA sẽ sử dụng giá trị khi lưu trữ một thực thể nếu chúng ta chú thích trường enum với @Enumerated(EnumType. SỢI DÂY)

Hãy tạo enum thứ hai

________số 8_______

Và hãy thêm nó vào lớp Article của chúng ta và chú thích nó bằng @Enumerated(EnumType. SỢI DÂY)

@Entity
public class Article {
    @Id
    private int id;

    private String title;

    @Enumerated(EnumType.ORDINAL)
    private Status status;

    @Enumerated(EnumType.STRING)
    private Type type;
}

Bây giờ khi duy trì một thực thể Article

Article article = new Article();
article.setId(2);
article.setTitle("string title");
article.setType(Type.EXTERNAL);

JPA sẽ thực thi câu lệnh SQL sau

insert 
into
    Article
    (status, title, type, id) 
values
    (?, ?, ?, ?)
binding parameter [1] as [INTEGER] - [null]
binding parameter [2] as [VARCHAR] - [string title]
binding parameter [3] as [VARCHAR] - [EXTERNAL]
binding parameter [4] as [INTEGER] - [2]

Với @Enumerated(EnumType. CHUỖI), chúng ta có thể thêm các giá trị enum mới hoặc thay đổi thứ tự của enum một cách an toàn. Tuy nhiên, đổi tên một giá trị enum vẫn sẽ phá vỡ dữ liệu cơ sở dữ liệu

Ngoài ra, mặc dù biểu diễn dữ liệu này dễ đọc hơn nhiều so với @Enumerated(EnumType. ORDINAL), nó cũng tiêu tốn nhiều dung lượng hơn mức cần thiết. Điều này có thể trở thành một vấn đề quan trọng khi chúng ta cần xử lý một lượng lớn dữ liệu

3. Sử dụng Chú thích @PostLoad và @PrePersist

Một tùy chọn khác mà chúng ta phải xử lý với các enum tồn tại trong cơ sở dữ liệu là sử dụng các phương thức gọi lại JPA tiêu chuẩn. Chúng tôi có thể ánh xạ qua lại các enum của mình trong các sự kiện @PostLoad và @PrePersist

Ý tưởng là có hai thuộc tính trong một thực thể. Cái đầu tiên được ánh xạ tới một giá trị cơ sở dữ liệu và cái thứ hai là trường @Transient chứa giá trị enum thực. Thuộc tính tạm thời sau đó được sử dụng bởi mã logic nghiệp vụ

Để hiểu rõ hơn về khái niệm này, hãy tạo một enum mới và sử dụng giá trị int của nó trong logic ánh xạ

public enum Priority {
    LOW(100), MEDIUM(200), HIGH(300);

    private int priority;

    private Priority(int priority) {
        this.priority = priority;
    }

    public int getPriority() {
        return priority;
    }

    public static Priority of(int priority) {
        return Stream.of(Priority.values())
          .filter(p -> p.getPriority() == priority)
          .findFirst()
          .orElseThrow(IllegalArgumentException::new);
    }
}

Chúng tôi cũng đã thêm Ưu tiên. of() để giúp dễ dàng lấy một thể hiện Ưu tiên dựa trên giá trị int của nó

Bây giờ, để sử dụng nó trong lớp Article của chúng ta, chúng ta cần thêm hai thuộc tính và triển khai các phương thức gọi lại

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
0

Bây giờ khi duy trì một thực thể Article

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
1

JPA sẽ kích hoạt truy vấn SQL sau

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
2

Mặc dù tùy chọn này cho phép chúng tôi linh hoạt hơn trong việc chọn biểu diễn của giá trị cơ sở dữ liệu so với các giải pháp được mô tả trước đó, nhưng nó không lý tưởng. Thật không đúng khi có hai thuộc tính đại diện cho một enum duy nhất trong thực thể. Ngoài ra, nếu chúng tôi sử dụng loại ánh xạ này, chúng tôi không thể sử dụng giá trị của enum trong các truy vấn JPQL.  

4. Sử dụng JPA 2. 1 Chú thích @Converter

Để khắc phục hạn chế của các giải pháp nêu trên, JPA 2. Bản phát hành đầu tiên đã giới thiệu một API chuẩn hóa mới có thể được sử dụng để chuyển đổi thuộc tính thực thể thành giá trị cơ sở dữ liệu và ngược lại. Tất cả những gì chúng ta cần làm là tạo một lớp mới triển khai javax. kiên trì. AttributeConverter và chú thích nó bằng @Converter

Hãy xem một ví dụ thực tế

Đầu tiên, chúng ta sẽ tạo một enum mới

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
3

Chúng ta cũng cần thêm nó vào lớp Article

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
4

Bây giờ hãy tạo một CategoryConverter mới

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
5

Chúng ta đã đặt giá trị autoApply của @Converter thành true để JPA sẽ tự động áp dụng logic chuyển đổi cho tất cả các thuộc tính được ánh xạ của một loại Danh mục. Nếu không, chúng ta phải đặt trực tiếp chú thích @Converter vào trường của thực thể

Bây giờ chúng ta hãy duy trì một thực thể Article

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
6

Sau đó, JPA sẽ thực thi câu lệnh SQL sau

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
7

Như chúng ta có thể thấy, chúng ta có thể chỉ cần đặt quy tắc chuyển đổi enum của riêng mình thành giá trị cơ sở dữ liệu tương ứng nếu chúng ta sử dụng giao diện AttributeConverter. Hơn nữa, chúng ta có thể thêm các giá trị enum mới hoặc thay đổi các giá trị hiện có một cách an toàn mà không làm hỏng dữ liệu đã tồn tại

Giải pháp tổng thể rất đơn giản để thực hiện và giải quyết tất cả các nhược điểm của các tùy chọn được trình bày trong các phần trước

5. Sử dụng Enums trong JPQL

Bây giờ chúng ta hãy xem việc sử dụng enums trong các truy vấn JPQL dễ dàng như thế nào

Để tìm tất cả các thực thể Bài viết có Danh mục. Thể loại THỂ THAO, chúng ta cần thực hiện câu lệnh sau

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
8

Điều quan trọng cần lưu ý là chúng ta cần sử dụng tên enum đủ điều kiện trong trường hợp này

Tất nhiên, chúng tôi không giới hạn các truy vấn tĩnh

Việc sử dụng các tham số được đặt tên là hoàn toàn hợp pháp

public enum Status {
    OPEN, REVIEW, APPROVED, REJECTED;
}
9

Ví dụ này trình bày một cách rất thuận tiện để tạo các truy vấn động

Ngoài ra, chúng tôi không cần sử dụng tên đủ điều kiện

6. Phần kết luận

Trong bài viết này, chúng tôi đã đề cập đến nhiều cách khác nhau để duy trì giá trị enum trong cơ sở dữ liệu. Chúng tôi đã trình bày các tùy chọn của mình khi sử dụng JPA trong phiên bản 2. 0 trở xuống cũng như một API mới có sẵn trong JPA 2. 1 trở lên

Điều đáng chú ý là đây không phải là khả năng duy nhất để xử lý enums trong JPA. Một số cơ sở dữ liệu, như PostgreSQL, cung cấp một loại cột chuyên dụng để lưu trữ các giá trị enum. Tuy nhiên, các giải pháp như vậy nằm ngoài phạm vi của bài viết này

Theo nguyên tắc thông thường, chúng ta phải luôn sử dụng giao diện AttributeConverter và chú thích @Converter nếu chúng ta đang sử dụng JPA 2. 1 hoặc muộn hơn

Làm cách nào để chèn enum vào MongoDB?

Các bước. Tạo và đăng ký nhà cung cấp codec với Mongo Code Registry mà Mongo sử dụng để xác định bộ giải mã Enum nào sẽ sử dụng giá trị Java Enum . Tạo và đăng ký bộ giải mã Enum cho ProcessType. Tạo và đăng ký Enum với DB.

MongoDB có hỗ trợ enum không?

Kiểu liệt kê, còn được gọi là enum, không được hỗ trợ nguyên bản trong SDK Java .

Làm cách nào để sử dụng chú thích @query trong khởi động mùa xuân với MongoDB?

Chú thích @Query khá đơn giản và dễ hiểu. @Query("mongo query") public List Khi phương thức findBy() được gọi, . Hãy nhớ rằng trong thời gian biên dịch, Spring Boot không biết trước loại truy vấn sẽ trả về.

Làm cách nào để tìm nạp dữ liệu từ MongoDB trong Spring Boot?

Bắt đầu với Spring Initializr .
Chọn Gradle hoặc Maven và ngôn ngữ bạn muốn sử dụng. Hướng dẫn này giả định rằng bạn đã chọn Java
Nhấp vào Phụ thuộc và chọn Dữ liệu mùa xuân MongoDB
Nhấp vào Tạo
Tải xuống tệp ZIP kết quả, đây là kho lưu trữ ứng dụng web được định cấu hình theo lựa chọn của bạn