使用Hibernate保存对象时收到以下错误
object references an unsaved transient instance - save the transient instance before flushing
使用Hibernate保存对象时收到以下错误
object references an unsaved transient instance - save the transient instance before flushing
当前回答
在我的例子中,当我试图使用对具有空id的实体的引用来检索相关实体时,发生了这种情况。
@Entity
public class User {
@Id
private Long id;
}
@Entity
public class Address {
@Id
private Long id;
@JoinColumn(name="user_id")
@OneToOne
private User user;
}
interface AddressRepository extends JpaRepository<Address, Long> {
Address findByUser(User user);
}
User user = new User(); // this is transient, does not have id populated
// user.setId(1L) // works fine if this is uncommented
addressRepository.findByUser(user); // throws exception
其他回答
不要使用Cascade.All,除非你真的需要。角色和权限具有双向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);
而如果对象只是一个“新”对象,那么它将抛出相同的错误。
或者,如果你想使用最小的“权力”(例如,如果你不想级联删除)来实现你想要的,使用
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
...
@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;
当我没有持久化父对象但我正在保存孩子时,我遇到了这个异常。为了解决这个问题,在同一个会话中,我保留了子对象和父对象,并在父对象上使用了CascadeType.ALL。
在我的例子中,这是由于双向关系的@ManyToOne一侧没有CascadeType导致的。更准确地说,我在@OneToMany端有CascadeType.ALL,而在@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;
还有一种可能会在休眠状态下导致此错误。您可以将对象A的未保存引用设置为附加的实体B,并希望持久化对象C。即使在这种情况下,您也会遇到上述错误。