Подтвердить что ты не робот

Объект ссылается на несохраненный экземпляр переходного процесса - сохраняет временный экземпляр перед промывкой

Я получаю следующую ошибку при сохранении объекта с помощью Hibernate

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

Ответ 1

Вы должны включить cascade="all" (если используете xml) или cascade=CascadeType.ALL (если используете аннотации) в своем сопоставлении коллекции.

Это происходит потому, что у вас есть коллекция в вашей сущности, и эта коллекция имеет один или несколько элементов, которых нет в базе данных. Задав указанные выше параметры, вы указываете спящий режим сохранять их в базе данных при сохранении их родительского элемента.

Ответ 2

Я считаю, что это может быть просто повторный ответ, но для уточнения я получил это на картинке @OneToOne, а также @OneToMany. В обоих случаях это был тот факт, что объект Child, который я добавлял в Parent, еще не был сохранен в базе данных. Поэтому, когда я добавил Child в Parent, а затем сохранил Parent, Hibernate будет бросать сообщение "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;
}

Ответ 3

Это происходит при сохранении объекта, когда Hibernate считает, что ему нужно сохранить объект, связанный с тем, который вы сохраняете.

У меня была эта проблема и я не хочу сохранять изменения для объекта, на который ссылается, поэтому я хотел, чтобы тип каскада был NONE.

Трюк заключается в том, чтобы убедиться, что идентификатор и VERSION в указанном объекте установлены так, чтобы Hibernate не думал, что ссылочный объект является новым объектом, который требует сохранения. Это сработало для меня.

Просмотрите все отношения в классе, который вы сохраняете, для разработки связанных объектов (и связанных объектов связанных объектов) и убедитесь, что ID и VERSION установлены во всех объектах дерева объектов.

Ответ 4

Или, если вы хотите использовать минимальные "полномочия" (например, если вы не хотите каскадное удаление) для достижения желаемого, используйте

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

...

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

Ответ 5

В моем случае это было вызвано отсутствием 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;

Ответ 6

Это произошло для меня при сохранении объекта, в котором существующая запись в базе данных имела значение NULL для поля, аннотированного с помощью @Version (для оптимистической блокировки). Обновление значения NULL до 0 в базе данных исправило это.

Ответ 7

Это не единственная причина ошибки. Я столкнулся с этим только сейчас для ошибки опечатки в моей кодировке, которая, как я полагаю, установила значение объекта, который уже был сохранен.

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

Я обнаружил ошибку, обнаружив точно, какая переменная вызвала ошибку (в данном случае String xid). Я использовал catch вокруг всего блока кода, который сохранил объект и напечатал трассировки.

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

Ответ 8

Если ваша коллекция имеет значение NULL, просто попробуйте: object.SetYouColection(null);

Ответ 9

Не используйте 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);

while, если объект является просто "новым", тогда он будет вызывать ту же ошибку.

Ответ 10

Чтобы добавить мои 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);

Здесь я устанавливаю существующий идентификатор отдела на новый экземпляр сотрудника без фактического получения элемента отдела сначала, так как я не хочу, чтобы другой запрос был выбран.

В некоторых сценариях deptId PKID приходит как null из метода вызова, и я получаю ту же ошибку.

Итак, обратите внимание на значения null для PK ID

Ответ 11

Я получаю эту ошибку, когда я использую

getSession().save(object)

но он работает без проблем, когда я использую

getSession().saveOrUpdate(object) 

Ответ 12

Помимо всех других хороших ответов, это может произойти, если вы используете merge для сохранения объекта и случайно забываете использовать объединенную ссылку объекта в родительском классе. рассмотрим следующий пример

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

В этом случае вы объединяете A, но забудьте использовать объединенный объект A. для решения проблемы вы должны переписать код следующим образом.

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

Ответ 13

Еще одна возможная причина: в моем случае я пытался сохранить ребенка перед сохранением родителя на совершенно новом объекте.

В модели User.java код был примерно таким:

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

Метод setNewPassword() создает запись в формате PasswordHistory и добавляет ее в коллекцию истории в User. Поскольку оператор create() еще не был выполнен для родителя, он пытался сохранить коллекцию объекта, который еще не был создан. Все, что мне нужно было сделать, чтобы исправить это, было перемещение вызова setNewPassword() после вызова create().

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

Ответ 14

Есть еще одна возможность, которая может вызвать эту ошибку в спящем режиме. Вы можете установить несохраненную ссылку вашего объекта A на прикрепленный объект B и хотите сохранить объект C. Даже в этом случае вы получите вышеупомянутую ошибку.

Ответ 15

Если вы используете Spring Data JPA, то добавление аннотации @Transactional к вашей реализации сервиса решит проблему.

Ответ 16

Ради полноты: A

org.hibernate.TransientPropertyValueException 

с сообщением

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

также произойдет, когда вы попытаетесь сохранить/объединить сущность со ссылкой на другую сущность, которая оказывается отсоединенной.

Ответ 17

Я тоже столкнулся с такой же ситуацией. Установив следующую аннотацию над свойством, оно решает вопрос об исключении.

Исключение, с которым я столкнулся.

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

Что заставило Hibernate бросить исключение:

Это исключение выдается на вашей консоли, потому что дочерний объект, который я присоединяю к родительскому объекту, в данный момент отсутствует в базе данных.

Предоставляя @OneToMany(cascade = {CascadeType.ALL}), он сообщает Hibernate о сохранении их в базе данных при сохранении родительского объекта.

Ответ 18

Простым способом решения этой проблемы является сохранение обоих объектов. сначала сохраните дочерний объект, а затем сохраните родительский объект. Поскольку родительский объект зависит от дочернего объекта для значения внешнего ключа.

Ниже простого изучения отношения "один к одному"

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

Ответ 19

Одной из возможных причин ошибки является отсутствие установки значения родительского объекта; например, для отношений между отделом и сотрудниками вы должны написать это, чтобы исправить ошибку:

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

Ответ 20

Существует так много возможностей этой ошибки, некоторые другие возможности также можно добавить на странице или странице редактирования. В моем случае я пытался сохранить объект AdvanceSalary. Проблема в том, что в редакции AdvanceSalary employee.employee_id имеет значение null. Поскольку при редактировании я не был установлен employee.employee_id. Я создал скрытое поле и установил его. мой код работает абсолютно нормально.

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

    }

Ответ 21

Я столкнулся с этим исключением, когда я не сохранил родительский объект, но я сохранял дочерний объект. Чтобы решить эту проблему, в одном сеансе я сохранил как дочерний, так и родительский объекты и использовал CascadeType.ALL для родительского объекта.

Ответ 22

Я думаю, потому что вы пытаетесь сохранить объект, который имеет ссылку на другой объект, который еще не сохранен, и поэтому он пытается в "стороне БД" поместить ссылку на несуществующую строку

Ответ 23

Случай 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;
    .
    .

}

В приведенном выше случае, когда родительский объект (Reference) и дочерний элемент (ReferenceAdditionalDetails) имеют отношение OneToOne, а также при попытке создания ссылочного объекта, а затем его дочернего элемента (ReferenceAdditionalDetails), вы получите одно и то же исключение. Поэтому, чтобы избежать исключения, вы должны установить значение null для дочернего класса, а затем создать родительский. (Пример кода)

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

Ответ 24

Эта проблема возникла у меня, когда я создал новую сущность и связанную сущность в методе, помеченном как @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);
}

Чтобы исправить, я выполнил запрос перед созданием новой сущности.