programing

최대 절전 모드 수정 방법 "개체가 저장되지 않은 임시 인스턴스를 참조 - 플러시하기 전에 임시 인스턴스를 저장" 오류

prostudy 2022. 5. 26. 23:03
반응형

최대 절전 모드 수정 방법 "개체가 저장되지 않은 임시 인스턴스를 참조 - 플러시하기 전에 임시 인스턴스를 저장" 오류

최대 절전 모드를 사용하여 개체를 저장할 때 다음 오류가 발생하는 경우

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

다음을 포함해야 함cascade="all"(xml을 사용하는 경우) 또는cascade=CascadeType.ALL(주석을 사용하는 경우) 컬렉션 매핑에 대한 정보를 참조하십시오.

이 문제는 사용자가 엔티티에 컬렉션이 있고 해당 컬렉션이 데이터베이스에 없는 하나 이상의 항목을 가지고 있기 때문에 발생한다.위의 옵션을 지정하여 부모 저장 시 최대 절전 모드에게 데이터베이스에 저장하도록 지시하십시오.

나는 이것이 그저 반복적인 대답일 수도 있다고 믿지만, 명확히 하기 위해서, 나는 이것을 가지고 있다.@OneToOne매핑뿐만 아니라@OneToMany. 두 가지 경우 모두, 그 사실이 바로 그 사실이었다.Child에 추가하고 있던 오브젝트Parent아직 데이터베이스에 저장되지 않았어그래서 내가 그 말을 덧붙이자면Child에게Parent, 그리고 나서 구했다.Parent겨울잠을 자면 모든게 엉망이 될거야"object references an unsaved transient instance - save the transient instance before flushing"상위 저장 시 메시지.

더하기 가cascade = {CascadeType.ALL}에서Parent's에 대한 언급.Child두 경우 모두 문제를 해결했다.이것이 그 사람을 구했다.Child그리고Parent.

반복해서 대답해서 미안해, 그냥 사람들을 위해 더 명확하게 하고 싶었어.

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

소개

JPA와 최대 절전 모드를 사용할 때 다음 4가지 상태 중 하나에 속할 수 있다.

  • 새로 만들기 - 최대 절전 모드 세션(예: 지속성 컨텍스트)과 연결되지 않았으며 데이터베이스 테이블 행에 매핑되지 않은 새로 생성된 개체는 새 또는 과도 상태로 간주된다.

버텨내려면 우리는 명시적으로 전화를 걸어야 한다.persist전이 지속성 메커니즘의 방법 또는 사용.

  • 지속성 - 영구 엔터티가 데이터베이스 테이블 행과 연결되었으며 현재 실행 중인 지속성 컨텍스트에 의해 관리되고 있음.

그러한 기업에 대한 변경사항은 (세션 플러시 시간 동안) 탐지되어 데이터베이스로 전파될 것이다.

  • 분리 - 현재 실행 중인 지속성 컨텍스트가 닫히면 이전에 관리하던 모든 엔티티가 분리된다.연속적인 변경은 더 이상 추적되지 않을 것이며 자동 데이터베이스 동기화는 일어나지 않을 것이다.

  • 제거됨 - JPA에서 관리 엔티티만 제거하도록 허용하도록 요구하지만, 최대 절전 모드에서는 (단, 단, 를 통해서만) 분리된 엔티티를 삭제할 수 있음remove메서드 콜(method call.

엔티티 상태 전환

엔터티를 한 상태에서 다른 상태로 이동하려면persistremove또는merge방법들

JPA 엔티티 상태

문제 해결

질문에서 설명하고 있는 문제:

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

새로운 상태의 엔티티를 관리 상태의 엔티티에 연결함으로써 발생한다.

이는 상위 엔티티의 일대다 컬렉션에 하위 엔티티를 연결할 때 발생할 수 있으며 컬렉션은 연결되지 않는다.cascade엔티티 상태 전환

따라서 다음과 같이 이 실패를 촉발한 엔터티 연결에 계단식(cascade)을 추가하여 이 문제를 해결할 수 있다.

@OneToOne

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

주목하라CascadeType.ALL에 대해 추가한 가치cascade기여하다

@OneToMany

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

다시, 더CascadeType.ALL@OneToMany협회

이제 캐스케이드가 양방향으로 제대로 작동하기 위해서는 부모조합과 자녀조합이 일치하는지 확인해야 한다.

@ManyToMany

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

@ManyToMany연결, 사용할 수 없음CascadeType.ALL또는orphanRemoval이렇게 하면 삭제 엔티티 상태 전환이 한 상위 엔티티에서 다른 상위 엔티티로 전파되기 때문이다.

그러므로, 위하여@ManyToMany연관성, 보통은 계단식으로CascadeType.PERSIST또는CascadeType.MERGE작전또는 다음으로 확장 가능DETACH또는REFRESH.

이러한 현상은 최대 절전 모드에서는 저장 중인 개체와 연결된 개체를 저장해야 한다고 생각할 때 발생한다.

나는 이 문제가 있었고 참조된 객체에 대한 변경사항을 저장하기를 원하지 않았기 때문에 계단식 유형을 NONE으로 하고 싶었다.

트릭은 참조된 객체의 ID와 VISION을 설정하여, 최대 절전 모드에서는 참조된 객체를 저장해야 하는 새 객체로 생각하지 않도록 하는 것이다.이것은 나에게 효과가 있었다.

저장 중인 클래스의 모든 관계를 검토하여 연결된 개체(및 연결된 개체의 연결 개체)를 확인하고 ID와 VISION이 개체 트리의 모든 개체에 설정되었는지 확인하십시오.

또는 최소한의 "힘"을 사용하여 원하는 것을 달성하려면(예: 계단식 삭제를 원하지 않는 경우) 사용하십시오.

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

...

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

내 경우는, 그것은 그 일이 없었던 것이 원인이었다.CascadeType에서@ManyToOne양방향 관계의 측면더 정확히 말하자면, 나는 그랬다.CascadeType.ALL…에@OneToMany옆에는 그것을 걸치고 있지 않았다.@ManyToOne. 추가CascadeType.ALL@ManyToOne문제를 해결했다.일대다 측면:

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

다대일 측면(문제의 원인)

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

다대일(추가하여 고정)CascadeType.PERSIST)

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

데이터베이스의 기존 레코드가 @Version(낙천적인 잠금을 위해)으로 주석을 단 필드에 대해 NULL 값을 갖는 엔티티를 지속할 때 이런 일이 발생했다.데이터베이스에서 NULL 값을 0으로 업데이트하면 이 문제가 해결되었다.

오류의 원인은 이것뿐만이 아니다.나는 코딩에서 오타 오류가 발생하여 방금 그것을 만났는데, 나는 이미 저장되어 있는 엔티티의 가치를 설정했다고 믿는다.

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

오류를 일으킨 변수를 정확히 찾아 오류를 감지했다(이 경우).String xid). a를 사용했다.catch실체를 구하고 흔적을 출력한 코드 블록 전체를 둘러싸고

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

사용하지 마십시오.Cascade.All네가 정말 그래야 할 때까지 Role그리고Permission양면성이 있다manyToMany인연의그럼 다음 코드가 잘 작동하겠네

    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);

만약 그 물체가 단지 "새" 물체라면, 그것은 같은 오류를 일으킬 것이다.

컬렉션을 무효화할 수 있는 경우 다음을 시도해 보십시오.object.SetYouColection(null);

다른 좋은 대답들 말고, 만약 당신이 이것을 사용한다면, 이것은 일어날 수 있다.merge개체를 유지하다가 실수로 상위 클래스에서 개체의 병합된 참조를 사용하는 것을 잊기 위해다음의 예를 고려하다.

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

은 이 이우를 A하지만 의 병합된 오브젝트를 사용하는 것을 잊는다.A문제를 해결하려면 이렇게 코드를 다시 작성해야 한다.

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

이 문제는 내가 새로운 실체와 관련 실체를 다음과 같이 표시된 방법으로 만들었을 때 나에게 일어났다.@Transactional그런 다음 저장하기 전에 쿼리를 수행하십시오.

@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);
}

수정하기 위해 새 엔티티를 만들기 전에 쿼리를 수행했다.

내 2센트를 덧붙이자면, 내가 실수로 보냈을 때도 같은 문제가 생겼어.null신분증으로아래 코드는 내 시나리오를 묘사한다(그리고 OP는 어떤 특정한 시나리오도 언급하지 않았다).

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);

여기서 나는 다른 선별된 질의를 해고하고 싶지 않기 때문에 실제로 부서 실체를 먼저 파악하지 않고 기존 부서 ID를 새 직원 인스턴스로 설정한다.

어떤 시나리오에서는deptIdPKID는 다음과 같이 제공된다.null전화하는 방법에서 같은 오류를 발견했어

자, 잘 지켜봐.null 값 값

나도 같은 상황에 직면했다.속성 위에 다음과 같은 주석을 설정하여 프롬프트된 예외를 해결했다.

내가 맞닥뜨린 예외.

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

극복하기 위해 사용한 주석.

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

최대 절전 모드 예외 발생:

이 예외는 당신의 콘솔에 저장된다. 왜냐하면 내가 부모 개체에 부착한 자식 개체가 그 순간에 데이터베이스에 존재하지 않기 때문이다.

제공함으로써@OneToMany(cascade = {CascadeType.ALL})이 명령은 부모 개체를 저장하는 동안 최대 절전 모드(Heaviate)에 해당 개체를 데이터베이스에 저장하도록 지시한다.

사용할 때 이 오류가 발생함

getSession().save(object)

하지만 내가 사용할 때는 문제없이 작동한다.

getSession().saveOrUpdate(object) 

완전성을 위해:a

org.hibernate.TransientPropertyValueException 

전갈을 받고

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

또한 당신이 분리된 다른 실체에 대한 참조를 가지고 실체를 지속/합병하려고 할 때 발생할 것이다.

또한 OneToMany 관계를 맺고 있는 상태에서 상위 엔티티의 목록에 하위 엔티티를 추가한 다음 (이 상위 엔티티를 저장하기 전에) 상위 엔티티를 통해 이 목록을 검색하려고 할 때 다음과 같은 경우가 발생할 수 있다.

Child childEntity = new Child();
parentEntity.addChild(childEntity);
parentEntity.getChildren(); // I needed the retrieval for logging, but one may need it for other reasons.
parentRepository.save(parentEntity);

상위 엔티티를 저장할 때 오류가 발생했음.앞줄에서 검색을 제거했다면 오류가 던져진 것은 아니지만 물론 해결책은 아니다.

해결책은 childEntity를 저장하고, 다음과 같이 저장된 하위 엔티티를 상위 엔티티에 추가하는 것이었습니다.

Child childEntity = new Child();
Child savedChildEntity = childRepository.save(childEntity);
parentEntity.addChild(savedChildEntity);
parentEntity.getChildren();
parentRepository.save(parentEntity);

Spring Data JPA를 하십시오.@Transactional서비스 구현에 대한 주석으로 문제를 해결할 수 있다.

또 다른 가능한 이유는, 내 경우, 나는 부모를 구하기 전에 아이를 구하려고 시도하고 있었는데, 완전히 새로운 개체였다.

User.java 모델에서 코드는 다음과 같았다.

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

setNewPassword() 메서드는 PasswordHistory 레코드를 생성하여 User의 기록 컬렉션에 추가한다.()생성문은 아직 부모에 대해 실행되지 않았기 때문에, 아직 생성되지 않은 실체의 집합에 저장하려고 하고 있었다.수정하기 위해 내가 해야 할 일은()를 만들기 위해 통화 후 setNewPassword() 통화를 옮기는 것이었다.

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

동면에서 이 오류를 일으킬 수 있는 또 다른 가능성이 있다.객체의 저장되지 않은 참조를 설정할 수 있음A부속 기관으로.B그리고 목적을 지속하고 싶다.C이 될 이런 경우에도 앞서 말한 오류를 얻게 된다.

이 오류의 가능성은 매우 많다. 다른 가능성들은 추가 페이지나 편집 페이지에도 있다.내 경우에는 AdvancedSalary라는 개체를 저장하려고 했다.문제는 AdvancedSalary worker.emperte_id 편집에서 null이라는 것이다. 왜냐하면 편집 시 나는 직원을 설정하지 않았기 때문이다.숨겨진필드를 만들고 설정했어.잘 작동해 정말내 코드는.

    @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;
        }

    }

나는 당신이 아직 지속되지 않은 다른 물체에 대한 참조가 있는 물체를 지속하려고 노력했기 때문에, 그것이 존재하지 않는 행에 대한 참조를 "DB 측"에서 시도하기 때문이라고 생각한다.

사례 1: 상위 항목을 생성하여 하위 항목에 상위 참조를 저장하고 다른 DELETE/UPDATE 쿼리(JPQL)를 저장할 때 이 예외가 발생함그래서 나는 부모를 만든 후와 동일한 부모 참조를 사용하여 자식을 만든 후에 새로 생성된 도면요소를 플러시()하기만 하면 된다.그것은 나에게 효과가 있었다.

사례 2:

부모반

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;
    . 
    .
    .
}

하위 클래스:

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;
    .
    .

}

상위(참조)와 하위(참조)가 OneToOne 관계를 갖는 경우, 그리고 참조 엔터티와 그 하위 엔터티를 생성하려고 할 때(참조 추가 상세 내역) 위와 같은 예외를 부여한다.따라서 예외를 방지하려면 자식 클래스에 대해 null을 설정한 다음 상위 클래스를 만들어야 한다.(표본 코드)

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

나의 경우 이슈는 완전히 달랐다.나는 c1과 c2 두 개의 수업이 있어.C1과 C2 사이의 종속성은 OneToMany이다.만약 내가 C1을 DB에 저장한다면 그것은 실수보다 더 중요한 것이었다.

이 문제의 해결은 소비자 요청에서 C2의 아이디를 먼저 얻고 리포지토리 호출을 통해 C2를 찾는 것이었다.그 후에 c2를 C1 객체에 저장한다.지금 내가 C1을 아끼고 있다면, 잘 되고 있어.

낙관적 잠금(@Version)을 도입한 후 모든 PUT HTTP 트랜잭션에 대해 동일한 오류를 직면하고 있었다.

엔터티를 업데이트할 때 해당 엔터티의 ID와 버전을 전송해야 한다.만약 어떤 엔티티 필드가 다른 엔티티와 관련이 있다면, 우리는 그 필드에 ID와 버전 값을 제공해야 한다. JPA는 먼저 그 관련 엔티티를 새로운 엔티티로 유지하려고 하지 않는다.

: 우리는 두 개의 실체 -> Vehicle(id,Car,version); Car(id, 버전, 브랜드); 업데이트/퍼시스트 차량 실체는 차량 실체의 Car 필드에 제공된 ID와 버전 필드가 있는지 확인하십시오.

이 문제를 해결하는 간단한 방법은 두 실체를 구하는 것이다.먼저 하위 엔티티를 저장한 다음 상위 엔티티를 저장하십시오.왜냐하면 지배기업은 자식기업에 의존하여 해외키값을 얻기 때문이다.

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);

오류의 한 가지 가능한 원인은 지배기업의 가치 설정이 존재하지 않기 때문이다. 예를 들어 부서-종업원 관계의 경우 오류를 수정하기 위해 다음과 같이 작성해야 한다.

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);

나는 부모님의 목적을 고수하지 않았지만 아이를 구하고 있을 때 이 예외에 직면했다.이 문제를 해결하기 위해 동일한 세션에서 하위 개체와 상위 개체를 모두 유지하고 CascadeType을 사용했다.모두 부모에게.

내 문제는 에 관련된 것이었다.@BeforeEachJUnit의그리고 (나의 경우) 관련 실체를 저장했더라도@ManyToOne)) 나도 같은 실수를 했다.

그 문제는 어쩐지 내가 부모에게 가지고 있는 순서와 관련이 있다.그 속성에 값을 할당하면 문제가 해결된다.

Ex. 일부 범주(하나 이상의 범주)를 가질 수 있는 엔티티 질문 및 엔티티 질문 순서가 있는 경우:

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

값을 할당해야 한다.question.setId(1L);

기본 클래스에 매핑된 생성자를 만드십시오.만약 당신이 기업 A, 기업 B에서 일대일 관계를 원한다면, 만약 당신이 A를 기본 클래스로 받아들인다면, A는 반드시 B를 논쟁으로 삼아야 한다.

참조URL: https://stackoverflow.com/questions/2302802/how-to-fix-the-hibernate-object-references-an-unsaved-transient-instance-save

반응형