Cách khắc phục đối tượng Hibernate đã tham chiếu một cá thể thoáng qua chưa được lưu - lưu phiên bản tạm thời trước khi xóa lỗi lỗi


610

Tôi nhận được lỗi sau khi lưu đối tượng bằng Hibernate

object references an unsaved transient instance - save the transient instance before flushing

1
Trong bối cảnh muốn là lỗi này? Là nó có hoặc không có biến tạm thời?
vijay

Câu trả lời:


803

Bạn nên bao gồm cascade="all"(nếu sử dụng xml) hoặc cascade=CascadeType.ALL(nếu sử dụng chú thích) trên ánh xạ bộ sưu tập của bạn.

Điều này xảy ra bởi vì bạn có một bộ sưu tập trong thực thể của mình và bộ sưu tập đó có một hoặc nhiều mục không có trong cơ sở dữ liệu. Bằng cách chỉ định các tùy chọn ở trên, bạn bảo ngủ đông để lưu chúng vào cơ sở dữ liệu khi lưu cha mẹ của chúng.


7
Đây không phải là ngầm? Không phải bạn luôn muốn Hibernate lưu chúng sao?
Marcus Leon

29
@Marcus - không, không phải vậy. Bạn có thể muốn xử lý chúng bằng tay.
Bozho

5
Bozho nói đúng. Tôi đã gặp phải trường hợp tôi có các bộ sưu tập mà tôi muốn quản lý thủ công vì kích thước của chúng hoặc do quy tắc kinh doanh không cho phép tất cả các đối tượng trong bộ sưu tập được lưu cùng một lúc.
Alex Marshall

26
Nó không chỉ xảy ra đối với các bộ sưu tập mà còn đơn giản từ một đến một ánh xạ
Sebastien Lorber

12
Sẽ không tốt hơn khi bắt đầu với CascadeType.PERSIST và sử dụng liên tục để lưu?
Sergii Shevchyk

248

Tôi tin rằng đây có thể chỉ là câu trả lời lặp lại, nhưng chỉ để làm rõ, tôi đã nhận được điều này trên @OneToOnebản đồ cũng như a @OneToMany. Trong cả hai trường hợp, thực tế là Childđối tượng tôi đã thêm vào Parentchưa được lưu trong cơ sở dữ liệu. Vì vậy, khi tôi thêm Childvào Parent, sau đó lưu Parent, Hibernate sẽ quăng "object references an unsaved transient instance - save the transient instance before flushing"nhắn khi lưu Phụ Huynh.

Thêm cascade = {CascadeType.ALL}vào các Parent'stham chiếu để Childgiải quyết vấn đề trong cả hai trường hợp. Điều này đã lưu ChildParent.

Xin lỗi cho bất kỳ câu trả lời lặp lại, chỉ muốn làm rõ thêm cho mọi người.

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}

7
Điều gì xảy ra nếu tôi không muốn xếp tầng tiết kiệm cho mối quan hệ @OneToOne? Khi tạo cả hai đối tượng lần đầu tiên, làm thế nào tôi có thể lưu vào cơ sở dữ liệu mà không kích hoạt ngoại lệ?
xtian

4
Điều gì sẽ xảy ra nếu tôi muốn cứu đứa trẻ trong một số trường hợp chứ không phải cho một số người khác?
Omaruchan

@xtian: Vậy thì bạn phải chăm sóc đúng thứ tự lưu vào cơ sở dữ liệu bằng cách duy trì các đối tượng với EntityManager. Trong cơ bản, bạn chỉ cần nói em.persist (object1); em.persist (object2); vv
kaba713

Tôi đã gặp vấn đề này cụ thể khi tôi sử dụng @Inherribution, trong trường hợp này là TABLE_PER_CLASS, tôi đã tham khảo một lớp con. CascadeType.ALL đã sửa nó.
Jim ReesPotter 17/03/18

Hoặc bạn đã tạo đối tượng thực thể của mình với new MyEntity(mà không đồng bộ hóa nó với cơ sở dữ liệu - xóa), thay vì lấy đối tượng được đồng bộ hóa từ cơ sở dữ liệu. Thực hiện các truy vấn Hibernate bằng cách sử dụng ví dụ đó thông báo cho bạn rằng những gì bạn mong đợi có trong cơ sở dữ liệu khác với những gì bạn có trong bộ nhớ ứng dụng của mình. Trong trường hợp này - chỉ cần đồng bộ hóa / nhận thực thể của bạn từ DB và sử dụng nó. Không có CascadeType.ALL là cần thiết sau đó.
Zon

67

Điều này xảy ra khi lưu một đối tượng khi Hibernate nghĩ rằng nó cần lưu một đối tượng được liên kết với đối tượng bạn đang lưu.

Tôi gặp vấn đề này và không muốn lưu các thay đổi vào đối tượng được tham chiếu nên tôi muốn loại tầng là KHÔNG.

Bí quyết là đảm bảo rằng ID và VERSION trong đối tượng được tham chiếu được đặt để Hibernate không nghĩ rằng đối tượng được tham chiếu là một đối tượng mới cần lưu. Điều này làm việc cho tôi.

Xem xét tất cả các mối quan hệ trong lớp bạn đang lưu để tìm ra các đối tượng liên quan (và các đối tượng liên quan của các đối tượng được liên kết) và đảm bảo rằng ID và VERSION được đặt trong tất cả các đối tượng của cây đối tượng.


4
Nhận xét này đưa tôi đi đúng hướng. Tôi đã gán một ví dụ mới của cha mẹ vào một tài sản của con nó. Vì vậy, NH nghĩ rằng họ là những trường hợp khác nhau.
elvin

2
Đúng. Điều này xảy ra nếu, ví dụ, id của đối tượng được liên kết không được bao gồm (ví dụ: nó bị bỏ qua bởi @JsonIgnore). Hibernate không có cách nào để xác định thực thể liên quan, vì vậy nó muốn lưu nó.
Rori Stumpf

36

Giới thiệu

Như tôi đã giải thích trong bài viết này khi sử dụng JPA và Hibernate, một thực thể có thể ở một trong 4 trạng thái sau:

  • Mới - Một đối tượng mới được tạo chưa từng được liên kết với Phiên Hibernate (còn gọi là Bối cảnh liên tục) và không được ánh xạ tới bất kỳ hàng trong bảng cơ sở dữ liệu nào được coi là ở trạng thái Mới hoặc Tạm thời.

    Để trở nên bền bỉ, chúng ta cần gọi persistphương thức một cách rõ ràng hoặc sử dụng cơ chế duy trì bắc cầu.

  • Kiên trì - Một thực thể liên tục đã được liên kết với một hàng của bảng cơ sở dữ liệu và nó được quản lý bởi Bối cảnh liên tục hiện đang chạy.

    Bất kỳ thay đổi nào được thực hiện cho một thực thể như vậy sẽ được phát hiện và lan truyền đến cơ sở dữ liệu (trong thời gian tuôn ra Phiên).

  • Tách rời - Khi Bối cảnh bền bỉ hiện đang chạy, tất cả các thực thể được quản lý trước đó sẽ bị tách ra. Những thay đổi kế tiếp sẽ không còn được theo dõi và sẽ không xảy ra đồng bộ hóa cơ sở dữ liệu tự động.

  • Đã xóa - Mặc dù JPA yêu cầu các thực thể được quản lý chỉ được phép xóa, Hibernate cũng có thể xóa các thực thể tách rời (nhưng chỉ thông qua một removecuộc gọi phương thức).

Thực thể chuyển trạng thái

Để di chuyển một thực thể từ một tiểu bang khác, bạn có thể sử dụng persist, removehoặc mergephương pháp.

Thực thể JPA

Khắc phục sự cố

Vấn đề bạn đang mô tả trong câu hỏi của bạn:

object references an unsaved transient instance - save the transient instance before flushing

được gây ra bằng cách liên kết một thực thể ở trạng thái Mới với một thực thể ở trạng thái Được quản lý .

Điều này có thể xảy ra khi bạn liên kết một thực thể con với một bộ sưu tập một-nhiều trong thực thể cha và bộ sưu tập không cascadechuyển trạng thái thực thể.

Vì vậy, như tôi đã giải thích trong bài viết này , bạn có thể khắc phục điều này bằng cách thêm tầng vào liên kết thực thể đã gây ra lỗi này, như sau:

các @OneToOnehiệp hội

@OneToOne(
    mappedBy = "post",
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private PostDetails details;

Lưu ý CascadeType.ALLgiá trị chúng tôi đã thêm cho cascadethuộc tính.

các @OneToManyhiệp hội

@OneToMany(
    mappedBy = "post", 
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();

Một lần nữa, CascadeType.ALLphù hợp cho các hiệp hội hai chiều@OneToMany .

Bây giờ, để tầng hoạt động chính xác theo hướng hai chiều, bạn cũng cần đảm bảo rằng các hiệp hội cha mẹ và con cái được đồng bộ hóa.

Kiểm tra bài viết này để biết thêm chi tiết về cách tốt nhất để đạt được mục tiêu này là gì.

các @ManyToManyhiệp hội

@ManyToMany(
    mappedBy = "authors",
    cascade = {
        CascadeType.PERSIST, 
        CascadeType.MERGE
    }
)
private List<Book> books = new ArrayList<>();

Trong một @ManyToManyliên kết, bạn không thể sử dụng CascadeType.ALLhoặc orphanRemovalvì điều này sẽ truyền sự chuyển đổi trạng thái thực thể từ cha mẹ này sang thực thể cha mẹ khác.

Do đó, đối với các @ManyToManyhiệp hội, bạn thường xếp tầng CascadeType.PERSISThoặc các CascadeType.MERGEhoạt động. Ngoài ra, bạn có thể mở rộng đó đến DETACHhoặc REFRESH.

Để biết thêm chi tiết về cách tốt nhất để lập bản đồ @ManyToManyliên kết, hãy xem bài viết này .


Giải thích đầy đủ và nhất quán! Làm tốt lắm!
lạnh

Bạn có thể tìm thấy hàng trăm lời giải thích chi tiết như vậy trong hướng dẫn Hibernate của tôi .
Vlad Mihalcea

30

Hoặc, nếu bạn muốn sử dụng "quyền hạn" tối thiểu (ví dụ: nếu bạn không muốn xóa tầng) để đạt được những gì bạn muốn, hãy sử dụng

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

...

@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;

11
Đây phải là câu trả lời được chấp nhận. CascadeType.ALL ist quá rộng
lilalinux

5
Kể từ Hibernate 5.2.8, dường như không có cách nào để đạt được hiệu quả tương tự với các chú thích JPA. Ví dụ: @ManyToMany(cascade={PERSIST, MERGE, REFRESH, DETACH})(tất cả trừ XÓA) không xếp tầng các bản cập nhật như của Hibernate CascadeType.SAVE_UPDATE.
jcsahnwaldt nói GoFundMonica

25

Trong trường hợp của tôi nó được gây ra bởi không có CascadeTypetrên @ManyToOnemặt của mối quan hệ hai chiều. Nói chính xác hơn, tôi đã CascadeType.ALL@OneToManybên và không có nó trên @ManyToOne. Thêm vào CascadeType.ALLđể @ManyToOnegiải quyết vấn đề. Một bên nhiều bên:

@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;

Nhiều phía (gây ra vấn đề)

@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;

Nhiều-một (cố định bằng cách thêm CascadeType.PERSIST)

@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;

Nếu tôi làm theo cách này và lưu thực thể cha mẹ, những gì đang xảy ra là có hai phần chèn trong bảng cha mẹ của tôi là hai hàng. Tôi nghĩ rằng bởi vì chúng tôi có tầng trên cả hai thực thể cha mẹ và con?
theprogrammer

18

Điều này xảy ra với tôi khi duy trì một thực thể trong đó bản ghi hiện có trong cơ sở dữ liệu có giá trị NULL cho trường được chú thích bằng @Version (để khóa tối ưu). Cập nhật giá trị NULL thành 0 trong cơ sở dữ liệu đã sửa lỗi này.


Đây phải là một câu hỏi mới và nó nên được thêm vào như một lỗi, ít nhất là ngoại lệ sai lệch. Điều này hóa ra là nguyên nhân của vấn đề của tôi.
BML

Điều này khắc phục vấn đề của tôi
Jad Chahine

11

Đây không phải là lý do duy nhất cho lỗi. Tôi đã gặp nó ngay bây giờ vì một lỗi đánh máy trong mã hóa của tôi, mà tôi tin rằng, đặt giá trị của một thực thể đã được lưu.

X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);

Tôi phát hiện ra lỗi bằng cách tìm chính xác biến nào gây ra lỗi (trong trường hợp này String xid). Tôi đã sử dụng catchxung quanh toàn bộ khối mã đã lưu thực thể và in dấu vết.

{
   code block that performed the operation
} catch (Exception e) {
   e.printStackTrace(); // put a break-point here and inspect the 'e'
   return ERROR;
}

1
Vấn đề tương tự với tôi. Sau đó, khi tôi tải lại thực thể cục bộ, đặt thuộc tính, sau đó lưu, nó hoạt động tốt.
CsBalazsHungary

8

Đừng sử dụng Cascade.Allcho đến khi bạn thực sự phải làm. RolePermissionmanyToManyquan hệ hai chiều . Sau đó, đoạn mã sau sẽ hoạt động tốt

    Permission p = new Permission();
    p.setName("help");
    Permission p2 = new Permission();
    p2.setName("self_info");
    p = (Permission)crudRepository.save(p); // returned p has id filled in.
    p2 = (Permission)crudRepository.save(p2); // so does p2.
    Role role = new Role();
    role.setAvailable(true);
    role.setDescription("a test role");
    role.setRole("admin");
    List<Permission> pList = new ArrayList<Permission>();
    pList.add(p);
    pList.add(p2);
    role.setPermissions(pList);
    crudRepository.save(role);

trong khi nếu đối tượng chỉ là một "mới", thì nó sẽ đưa ra cùng một lỗi.


1
là chính xác 100%, Cascade. Tất cả là giải pháp lười biếng và chỉ nên được áp dụng khi được yêu cầu. đầu tiên, nếu thực thể đã tồn tại, hãy kiểm tra xem nó có được tải trong trình quản lý thực thể hiện tại không, nếu không tải nó.
Renato Mendes

7

Nếu bộ sưu tập của bạn là nullable, hãy thử: object.SetYouColection(null);


Đây hoàn toàn là vấn đề của tôi. Tôi không bao giờ có thể đoán tôi phải tự đặt nó thành null.
Deadron

Đây cũng là vấn đề của tôi. Tôi đã không sử dụng một bộ sưu tập, vì vậy ban đầu tôi đã không thử nó, nhưng tôi đã đặt đối tượng của mình thành null và bây giờ nó hoạt động.
Thức ăn gia súc

5

Để thêm 2 xu của tôi, tôi đã gặp vấn đề tương tự khi tôi vô tình gửi nulldưới dạng ID. Mã bên dưới mô tả kịch bản của tôi (và OP không đề cập đến bất kỳ kịch bản cụ thể nào) .

Employee emp = new Employee();
emp.setDept(new Dept(deptId)); // --> when deptId PKID is null, same error will be thrown
// calls to other setters...
em.persist(emp);

Ở đây tôi đang đặt id bộ phận hiện tại thành một cá thể nhân viên mới mà không thực sự có được thực thể bộ phận trước, vì tôi không muốn truy vấn chọn khác để kích hoạt.

Trong một số trường hợp, deptIdPKID xuất phát nulltừ phương thức gọi và tôi gặp lỗi tương tự.

Vì vậy, hãy theo dõi các nullgiá trị cho PK ID


Nếu nó không có giá trị thì sao?
cp vipin

Tôi có vấn đề tương tự. Tôi nhận được ngoại lệ khi deptID của tôi bằng 0. Mọi giá trị khác lớn hơn 0 hoạt động. Thật buồn cười là tôi có một phòng với id = 0.
Gustavo

5

Vấn đề này xảy ra với tôi khi tôi tạo một thực thể mới và một thực thể liên quan trong một phương thức được đánh dấu là @Transactional, sau đó thực hiện một truy vấn trước khi lưu. Ví dụ

@Transactional
public someService() {
    Entity someEntity = new Entity();
    AssocaiatedEntity associatedEntity = new AssocaitedEntity();
    someEntity.setAssociatedEntity(associatedEntity);
    associatedEntity.setEntity(someEntity);

    // Performing any query was causing hibernate to attempt to persist the new entity. It would then throw an exception
    someDao.getSomething();

    entityDao.create(someEntity);
}

Để khắc phục, tôi đã thực hiện truy vấn trước khi tạo thực thể mới.


4

bên cạnh tất cả các câu trả lời hay khác, điều này có thể xảy ra nếu bạn sử dụng mergeđể duy trì một đối tượng và vô tình quên sử dụng tham chiếu hợp nhất của đối tượng trong lớp cha. xem xét ví dụ sau

merge(A);
B.setA(A);
persist(B);

Trong trường hợp này, bạn hợp nhất Anhưng quên sử dụng đối tượng hợp nhất của A. để giải quyết vấn đề bạn phải viết lại mã như thế này.

A=merge(A);//difference is here
B.setA(A);
persist(B);

3

tôi gặp lỗi này khi sử dụng

getSession().save(object)

nhưng nó không hoạt động khi tôi sử dụng

getSession().saveOrUpdate(object) 

3

Tôi cũng phải đối mặt với tình huống tương tự. Bằng cách thiết lập chú thích sau trên thuộc tính làm cho nó giải quyết ngoại lệ được nhắc.

Ngoại lệ tôi phải đối mặt.

Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.model.Car_OneToMany

Để khắc phục, chú thích tôi đã sử dụng.

    @OneToMany(cascade = {CascadeType.ALL})
    @Column(name = "ListOfCarsDrivenByDriver")
    private List<Car_OneToMany> listOfCarsBeingDriven = new ArrayList<Car_OneToMany>();

Điều gì đã khiến Hibernate ném ngoại lệ:

Ngoại lệ này được ném vào bàn điều khiển của bạn vì đối tượng con tôi đính kèm với đối tượng cha không có trong cơ sở dữ liệu tại thời điểm đó.

Bằng cách cung cấp @OneToMany(cascade = {CascadeType.ALL}), nó báo cho Hibernate lưu chúng vào cơ sở dữ liệu trong khi lưu đối tượng cha.


2

Vì lợi ích của sự hoàn chỉnh: A

org.hibernate.TransientPropertyValueException 

với tin nhắn

object references an unsaved transient instance - save the transient instance before flushing

cũng sẽ xảy ra khi bạn cố gắng duy trì / hợp nhất một thực thể với một tham chiếu đến một thực thể khác có thể bị tách ra .


1

Một lý do có thể khác: trong trường hợp của tôi, tôi đã cố gắng cứu đứa trẻ trước khi cứu cha mẹ, trên một thực thể hoàn toàn mới.

Mã này giống như thế này trong mô hình User.java:

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.setNewPassword(password);
this.timeJoin = new Date();
create();

Phương thức setNewPassword () tạo bản ghi PasswordHistory và thêm nó vào bộ sưu tập lịch sử trong Người dùng. Vì câu lệnh tạo () chưa được thực thi cho cha mẹ, nên nó đã cố lưu vào bộ sưu tập của một thực thể chưa được tạo. Tất cả những gì tôi phải làm để khắc phục nó là di chuyển cuộc gọi setNewPassword () sau cuộc gọi để tạo ().

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.timeJoin = new Date();
create();
this.setNewPassword(password);

1

Có một khả năng khác có thể gây ra lỗi này trong chế độ ngủ đông. Bạn có thể đặt tham chiếu chưa được lưu của đối tượng của mình Athành một thực thể đính kèm Bvà muốn duy trì đối tượng C. Ngay cả trong trường hợp này, bạn sẽ nhận được lỗi đã nói ở trên.


1

Nếu bạn đang sử dụng Spring Data JPA thì việc thêm @Transactionalchú thích vào triển khai dịch vụ của bạn sẽ giải quyết được vấn đề.


1

Tôi nghĩ là bởi vì bạn đã cố gắng duy trì một đối tượng có tham chiếu đến một đối tượng khác chưa tồn tại và vì vậy nó cố gắng ở "bên DB" để đặt tham chiếu đến một hàng không tồn tại


0

Cách đơn giản để giải quyết vấn đề này là lưu cả hai thực thể. đầu tiên lưu thực thể con và sau đó lưu thực thể cha. Bởi vì thực thể cha mẹ phụ thuộc vào thực thể con cho giá trị khóa ngoài.

Dưới đây kiểm tra đơn giản mối quan hệ 1-1

insert into Department (name, numOfemp, Depno) values (?, ?, ?)
Hibernate: insert into Employee (SSN, dep_Depno, firstName, lastName, middleName, empno) values (?, ?, ?, ?, ?, ?)

Session session=sf.openSession();
        session.beginTransaction();
        session.save(dep);
        session.save(emp);

1
Điều ngược lại - thực thể con giữ giá trị FK và phụ thuộc vào cha mẹ nên bạn cần lưu cha mẹ trước! Trong khối mã bạn có nó đúng.
Sõber 17/12/17

0

Một nguyên nhân có thể gây ra lỗi là sự không tồn tại của cài đặt giá trị của thực thể mẹ; ví dụ: đối với mối quan hệ nhân viên phòng ban, bạn phải viết điều này để sửa lỗi:

Department dept = (Department)session.load(Department.class, dept_code); // dept_code is from the jsp form which you get in the controller with @RequestParam String department
employee.setDepartment(dept);

0

Có rất nhiều khả năng của lỗi này, một số khả năng khác cũng có trên trang thêm hoặc trang chỉnh sửa. Trong trường hợp của tôi, tôi đã cố gắng cứu một đối tượng AdvanceSalary. Vấn đề là trong chỉnh sửa nhân viên AdvanceSalary.employee_id là null Bởi vì khi chỉnh sửa tôi không đặt nhân viên.employee_id. Tôi đã thực hiện một trường ẩn và thiết lập nó. mã của tôi hoạt động hoàn toàn tốt.

    @Entity(name = "ic_advance_salary")
    @Table(name = "ic_advance_salary")
    public class AdvanceSalary extends BaseDO{

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Integer id;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "employee_id", nullable = false)
        private Employee employee;

        @Column(name = "employee_id", insertable=false, updatable=false)
        @NotNull(message="Please enter employee Id")
        private Long employee_id;

        @Column(name = "advance_date")
        @DateTimeFormat(pattern = "dd-MMM-yyyy")
        @NotNull(message="Please enter advance date")
        private Date advance_date;

        @Column(name = "amount")
        @NotNull(message="Please enter Paid Amount")
        private Double amount;

        @Column(name = "cheque_date")
        @DateTimeFormat(pattern = "dd-MMM-yyyy")
        private Date cheque_date;

        @Column(name = "cheque_no")
        private String cheque_no;

        @Column(name = "remarks")
        private String remarks;

        public AdvanceSalary() {
        }

        public AdvanceSalary(Integer advance_salary_id) {
            this.id = advance_salary_id;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public Employee getEmployee() {
            return employee;
        }

        public void setEmployee(Employee employee) {
            this.employee = employee;
        }


        public Long getEmployee_id() {
            return employee_id;
        }

        public void setEmployee_id(Long employee_id) {
            this.employee_id = employee_id;
        }

    }

0

Tôi đã phải đối mặt với ngoại lệ này khi tôi không kiên trì đối tượng cha mẹ nhưng tôi đang cứu đứa trẻ. Để giải quyết vấn đề, trong cùng một phiên, tôi đã duy trì cả đối tượng con và đối tượng cha mẹ và sử dụng CascadeType.ALL trên cha mẹ.


0

Trường hợp 1: Tôi đã nhận được ngoại lệ này khi tôi đang cố gắng tạo cha mẹ và lưu tham chiếu cha mẹ đó cho con của nó và sau đó một số truy vấn XÓA / CẬP NHẬT khác (JPQL). Vì vậy, tôi chỉ tuôn ra () thực thể mới được tạo sau khi tạo cha mẹ và sau khi tạo con bằng cách sử dụng cùng tham chiếu cha. Nó làm việc cho tôi.

Trường hợp 2:

Lớp phụ huynh

public class Reference implements Serializable {

    @Id
    @Column(precision=20, scale=0)
    private BigInteger id;

    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedOn;

    @OneToOne(mappedBy="reference")
    private ReferenceAdditionalDetails refAddDetails;
    . 
    .
    .
}

Lớp trẻ em:

public class ReferenceAdditionalDetails implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @OneToOne
    @JoinColumn(name="reference",referencedColumnName="id")
    private Reference reference;

    private String preferedSector1;
    private String preferedSector2;
    .
    .

}

Trong trường hợp trên, khi cha mẹ (Tham chiếu) và con (ReferenceAdditableDetails) có mối quan hệ OneToOne và khi bạn cố gắng tạo thực thể Tham chiếu và sau đó là con của nó (ReferenceAdditableDetails), nó sẽ cung cấp cho bạn ngoại lệ tương tự. Vì vậy, để tránh ngoại lệ, bạn phải đặt null cho lớp con và sau đó tạo cha mẹ. (Mã mẫu)

.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.

0

Vấn đề của tôi liên quan đến @BeforeEachJUnit. Và ngay cả khi tôi đã lưu các thực thể liên quan (trong trường hợp của tôi @ManyToOne), tôi vẫn gặp lỗi tương tự.

Vấn đề là bằng cách nào đó liên quan đến trình tự mà tôi có trong cha mẹ tôi. Nếu tôi gán giá trị cho thuộc tính đó, vấn đề sẽ được giải quyết.

Ví dụ. Nếu tôi có Câu hỏi thực thể có thể có một số loại (một hoặc nhiều) và Câu hỏi thực thể có một chuỗi:

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "feedbackSeq")
@Id
private Long id;

Tôi phải gán giá trị question.setId(1L);


0

Chỉ cần tạo Con Contor của ánh xạ trong lớp cơ sở của bạn. Giống như nếu bạn muốn quan hệ Một-Một trong Thực thể A, Thực thể B. nếu bạn đang lấy A làm lớp cơ sở, thì A phải có Trình xây dựng có B làm đối số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.