2016-11-16 59 views
6

Tôi gặp sự cố trong đó tôi không thể duy trì hoặc hợp nhất đối tượng chỉ chứa ID và bộ sưu tập các đối tượng khác. Nếu tôi thêm một trường khác, nó sẽ thực hiện giao dịch như bình thường. Ngoài ra, nếu tôi thay đổi chiến lược tạo ID thành AUTO nó cũng sẽ hoạt động.Làm thế nào để duy trì một thực thể chỉ chứa một bộ sưu tập và một ID?

Những người còn lại trong nhóm của tôi sử dụng "IDENTITY" thay vì "AUTO", vì vậy tôi muốn nhất quán với họ. Các thực thể của họ không chỉ là ID + Bộ sưu tập, vì vậy nó hoạt động tốt cho họ. Sau đây là những gì tôi muốn làm cho công việc:

@Entity 
public class Filter implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }) 
    private ArrayList<Rule> rules = new ArrayList<>(); 

    public Filter() { 

    } 

} 

ErrorMessage:

org.apache.openjpa.persistence.PersistenceException: ERROR: syntax error at or near ")" 
    Position: 25 {prepstmnt 693640431 INSERT INTO Filter() VALUES()} [code=0, state=42601] 
FailedObject: [email protected] 

Về cơ bản, vì nó chỉ là một ID và một tham Bảng, nó chết khi cố gắng kéo dài hoặc hợp nhất các bộ lọc không có bất kỳ trường nào.

Cách giải quyết

  • Thay đổi GenerationType.IDENTITY để GenerationType.AUTO.

    -Các chỉ con dường như là chìa khóa chính bắt đầu từ ban đầu để nhảy xung quanh bằng 50, sau đó nó bắt đầu incrementing bởi 1.

  • Thay đổi GenerationType để TABLE

    -Đây có vẻ là những gì AUTO được chọn.

  • Thêm trường tùy ý vào thực thể (ví dụ: String test = "test").

    -Đơn giản làm cho thực thể có thêm một trường nữa làm cho trường đó tồn tại. Tuy nhiên, tôi không cần lĩnh vực này ở đó; Tôi chỉ muốn một bộ sưu tập

  • Làm cho các mối quan hệ hai chiều.

    -Bằng cách tạo mối quan hệ hai chiều, các bảng có id sẽ quay lại (thay vì chỉ là id). Điều này chỉ hoạt động vì Bộ lọc được sở hữu bởi một bản ghi khác.

+0

Nếu nhà cung cấp JPA của bạn không hỗ trợ có câu lệnh INSERT không có cột thì hãy tăng BUG lên đó. Tôi làm điều đó với nhà cung cấp mà tôi sử dụng (DataNucleus) và nó tạo ra đúng SQL. –

+0

Sử dụng AUTO không thực sự là câu trả lời vì AUTO có nghĩa là hãy để nó cho nhà cung cấp chiến lược sử dụng, và họ chỉ có thể sử dụng IDENTITY dưới các bìa kết thúc với cùng một vấn đề. –

+0

Đã bị xóa khỏi tác giả – garfield

Trả lời

0

Một giải pháp tốt sẽ làm cho mã hai chiều, như bạn đã chỉ ra và sử dụng chú thích "@PrePersist", để đặt id thành đối tượng "Quy tắc". Một cái gì đó như:

Rule.java

@Entity 
public class Rule implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    private String description; 

    @ManyToOne 
    private Filter filter; 

    // getters, setters, equals, hashcode, toString... 
} 

Filter.java

@Entity 
public class Filter implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }, mappedBy="filter") 
    private List<Rule> rules = new ArrayList<>(); 

    @PrePersist 
    public void prePersist() { 
     if (rules != null) { 
      rules.forEach(item -> item.setFilter(this)); 
     } 
    } 

    // getters, setters, equals, hashcode, toString... 
} 

FilterRepository.java

@Repository 
public interface FilterRepository extends JpaRepository<Filter, Integer> { } 

AnUnitTest.java

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class AnUnitTest { 
    @Autowired 
    private FilterRepository filterRepository; 

    @After 
    public void clearDatabase() { 
     bodyPartRespository.deleteAll(); 

     filterRepository.deleteAll(); 
    } 

    @Test 
    public void testFilterRules() { 
     Rule aRule = Rule.builder() 
       .description("A") 
       .build(); 
     Rule anotherRule = Rule.builder() 
       .description("B") 
       .build(); 

     Filter filter = Filter.builder() 
       .rules(Arrays.asList(aRule, anotherRule)) 
       .build(); 

     filterRepository.saveAndFlush(filter); 

     List<Filter> all = filterRepository.findAll(); 

     all.forEach(System.out::println); 
    } 
} 

Đoạn mã trên chạy tốt cho tôi.

Tôi hy vọng điều này sẽ khắc phục được sự cố của bạn.

Chúc mừng, Nikolas.

0

tôi thực hiện có vấn đề của bạn với 4 ví dụ khác nhau:

  1. Chỉ cần ID

    @Entity public class Trường hợp1 thực hiện Serializable {

    private static thức dài serialVersionUID = 1L;

    @Id @GeneratedValue (strategy = GenerationType.IDENTITY) riêng Dài id;

    // ... }

  2. ID + 1 Chuỗi cột

    @Entity public class Trường hợp2 thực hiện Serializable {

    private static thức dài serialVersionUID = 1L ;

    @Id @GeneratedValue (strategy = GenerationType.IDENTITY) riêng Dài id; tên chuỗi riêng;

    // ... }

  3. ID + 1 OneToMany hiệp hội

a. với cascade = {} CascadeType.ALL

> @Entity 
> public class Case3 implements Serializable { 
>   
> private static final long serialVersionUID = 1L; 
>    
> @Id 
> @GeneratedValue(strategy = GenerationType.IDENTITY) 
> private Long id; 
> @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }) 
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();   
> // ... 
>} 

b. mà không cascade = {} CascadeType.ALL

> @Entity 
> public class Case4 implements Serializable { 
>   
> private static final long serialVersionUID = 1L; 
>    
> @Id 
> @GeneratedValue(strategy = GenerationType.IDENTITY) 
> private Long id; 
> 
> @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true) 
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();  
> // ... 
>} 

Kết quả là tốt với các truy vấn SQL (thử nghiệm dưới PostgreSQL 9.3). Nhưng với javax.persistence, tôi đã có một kết quả khác nhau:

  1. Trường hợp 1: Mô tả ngoại lệ: Danh sách các trường để chèn vào bảng [DatabaseTable (Trường hợp1)] trống. Bạn phải xác định ít nhất một ánh xạ cho bảng này.
  2. Trường hợp 2: Hoạt động tốt.
  3. Trường hợp 3: Ngăn xếp ngoại lệ cục bộ: Ngoại lệ [EclipseLink-4002] (Dịch vụ kiên trì Eclipse - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException Internal Ngoại lệ: org.postgresql.util.PSQLException: ERREUR: la valeur d'une clé dupliquée rompt la contrainte độc ​​đáo «rule_code_key»
  4. Trường hợp 4: Mô tả ngoại lệ: Danh sách các trường chèn vào bảng [DatabaseTable (case4)] rỗng. Bạn phải xác định ít nhất một ánh xạ cho bảng này.

Việc giải thích lỗi trên trường hợp 1, 3 & 4 thật đơn giản.

  1. Đối với Trường hợp 3, khi bạn có cascade = {} CascadeType.ALL các orm cố gắng để tồn tại Rule trước sự bền bỉ Lọc và tất cả mọi thứ phụ thuộc vào nhu cầu, cho tôi trường hợp Rule nó đã tồn tại.

  2. Đối với Trường hợp 1 & 4, bạn đang cố gắng để tồn tại chỉ là id của Lọc trên bàn N ° 1 và id của quy tắc + id của Lọc trên Tham Bảng. Điều đó có nghĩa là Bộ lọc chỉ có ID Đồng nghĩa của một vấn đề thiết kế = Bạn phải xác định ít nhất một ánh xạ cho bảng này.

Các vấn đề liên quan