简体   繁体   中英

Saving lazy child is causing: TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

I'm experimenting with lazy loading entities in hibernate but could not get over the error above. I'm basically playing with 2 entities: User and Role:

public class User implements Serializeable {
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "T_USER_ROLE", joinColumns = @JoinColumn(name = "USER_ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
    private Set<Role> roles = new HashSet<Role>();
}

public class Role implements Serializeable { }

And then I have an action bean that creates the User entity, let's called this approach 1:

user.getRoles().add(roleService.findByName(RolesEnum.ADMIN.toString()));
em.persist(user);

And then I tried to persist the user entity first before setting the roles and updating but it also failed:

userService.create(user);
User user = userService.findById(user.getId());
Set<Role> roles = new HashSet<Role>();
roles.add(roleService.findByName(RolesEnum.MEMBER.toString()));
user.setRoles(roles);
userService.update(user, true);

Note that:

  • userService.create = persist
  • userService.update = merge
  • MEMBER role already exists in roles table
  • I also tried fetching the roles: entity.getRoles();

Below is the complete error log:

java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.test.Role org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)

This problem is solved by binding the entity manager to conversation scope and using seam-solder.

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
public @interface TempJpa { }

@ExtensionManaged
@ConversationScoped
@Produces
@PersistenceUnit(unitName="tempDataSource")
@TempJpa
private EntityManagerFactory emf;

@Inject
@TempJpa
protected EntityManager em;

But the next question is why?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM