JPA - ManyToMany bidirecional com os dois lados sendo owner

Olá a todos, estou com o seguinte problema:

Tenho duas entidades, User e Role, com um relacionamento NxM bidirecional. A entidade “chefe” é a User.
Quando adiciono um role a um user e salvo o user, uma linha na tabela do relacionamento é criada.
Mas quando adiciono um user a um role a relação não é estabelecida.

Preciso que seja desse jeito pois terei duas telas, uma para detalhes do usuário e outra pra detalhes do role.
Na tela do usuário pode-se definir quais roles ele possui e na tela de roles pode-se definir quais users são membros daquela role.

Não sei se fui muito claro. Talvez um pouco de código ajude:

Entidade User:

@Entity @Table(name = "AC_USER") @SequenceGenerator(name="SEQ_USER", allocationSize=1)
public class User implements Serializable {

    @Id @GeneratedValue(generator="SEQ_USER") @Column(name = "ID_USER")
    private Integer id;

    private String firstName;
    private String lastName;
    private String userName;
    private String password;

    @ManyToMany(cascade=CascadeType.REFRESH)
    @JoinTable(name="AC_USER_ROLE", uniqueConstraints = @UniqueConstraint(columnNames={"ID_USER", "ID_ROLE"}),
    joinColumns = {@JoinColumn(name="ID_USER", referencedColumnName="ID_USER", nullable=false)},
    inverseJoinColumns = {@JoinColumn(name="ID_ROLE", referencedColumnName="ID_ROLE", nullable=false)})
    private List<Role> roles;

Entidade Role:

@Entity @Table(name = "AC_ROLE") @SequenceGenerator(name="SEQ_ROLE", allocationSize=1)
public class Role implements Serializable {
    
    @Id @GeneratedValue(generator="SEQ_ROLE") @Column(name = "ID_ROLE")
    private Integer id;

    private String name;
    private String description;

    @ManyToMany(mappedBy="roles")
    private List<User> users;

Para testar:

public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("TesteJpaPU");
        EntityManager em  = emf.createEntityManager();

        User user = new User("User", "", "user", "123");
        Role role = new Role("Admin", "");

        em.getTransaction().begin();

        // Assim funciona
        em.persist(role);

        user.setRoles(new ArrayList<Role>());
        user.getRoles().add(role);

        em.persist(user);

        // Assim não funciona
        em.persist(user);

        role.setUsers(new ArrayList<User>());
        role.getUsers().add(user);

        em.persist(role);

        em.getTransaction().commit();
        
        em.close();
        emf.close();
    }

Eaí? O que quero fazer é possível?

Daniel,

Experimente fazer assim e nos avise sobre o resultado.

@Entity @Table(name = "AC_USER")
@SequenceGenerator(name="SEQ_USER", allocationSize=1)   
public class User implements Serializable {   
  
    @Id 
	@GeneratedValue(generator="SEQ_USER")
	@Column(name = "ID_USER")   
    private Integer id;   
  
    private String firstName;   
    private String lastName;   
    private String userName;   
    private String password;   
	
	@ManyToMany(
        fetch=FetchType.EAGER,
        targetEntity = Role.class,
        cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.REFRESH}
    )
    @JoinTable(
        name="AC_USER_ROLE",
        joinColumns={@JoinColumn(name="ID_USER", referencedColumnName="ID_USER", nullable=false)},
        inverseJoinColumns={ @JoinColumn( name="ID_ROLE", referencedColumnName="ID_ROLE", nullable=false)},
        uniqueConstraints={ @UniqueConstraint(columnNames={ "ID_USER", "ID_ROLE"})}
    )
    private Set<Role> roles;  

	public User(String firstName, String lastName, String userName, String password) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.userName = userName;
		this.password = password;
		this.roles = new HashSet<Role>();
	}
	
	public User() {
		this.roles = new HashSet<Role>();
	}
	
	public void addRole(Role role) {
		if(role != null) {
			this.roles.add(role);
		}
	}
}

@Entity @Table(name = "AC_ROLE") 
@SequenceGenerator(name="SEQ_ROLE", allocationSize=1)   
public class Role implements Serializable {   
       
    @Id @GeneratedValue(generator="SEQ_ROLE") 
	@Column(name = "ID_ROLE")   
    private Integer id;   
  
    private String name;   
    private String description;   
  
    @ManyToMany(
        cascade={CascadeType.PERSIST, CascadeType.MERGE},
        mappedBy="roles",
        targetEntity=User.class
    )
	private Set<User> users;  

	public Role() {
		this.users = new HashSet<User>();
	}
	
	public Role(String name, String description) {
		this.name = name;
		this.description = description;
		this.users = new HashSet<User>();
	}
	
	public void addUser(User user) {
		if(user != null) {
			this.users.add(user);
		}
	}
}

public static void main(String[] args) {   
	EntityManagerFactory emf = Persistence.createEntityManagerFactory("TesteJpaPU");   
	EntityManager em  = emf.createEntityManager();   

	User user = new User("User01", "", "user01", "123");   
	Role role = new Role("Admin01", "");   

	// Direção User para Role
	em.getTransaction().begin();   
    user.addRole(role);
	em.persist(user);   
	em.getTransaction().commit();   

	User user = new User("User02", "", "user02", "123");   
	Role role = new Role("Admin02", "");   
	
	// Direção Role para User
	em.getTransaction().begin();   
	role.addUser(user);
	em.persist(role);   
	em.getTransaction().commit();   
	
	em.close();   
	emf.close();   
}

@braços

[quote=ccllss]Daniel,

Experimente fazer assim e nos avise sobre o resultado.

@braços[/quote]

Opa ccllss, cara não funcionou não. Continua gerando o relacionamento só quando persisto a entidade com a @JoinTable.

Conhece algum outro modo? Obrigado!