2015-12-02 9 views
0

Я работаю над веб-приложением, работающим на GlassFish 4.1.1, с использованием EclipseLink 2.6.1. У меня однонаправленное отношение ManyToMany между пользователями и проектами, и когда я удаляю элементы из User.projects и объединяю User, строки соединения не удаляются в базе данных. Я сделал меньше демонстрационное приложение, чтобы выделить его: классJPA Однонаправленный ManyToMany не удалось удалить

Пользователь:

@Entity 
@Table(name = "demouser") 
public class DemoUser implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DemoUserSeq") 
    @SequenceGenerator(name = "DemoUserSeq", sequenceName = "demouser_userid_seq", allocationSize = 1) 
    @Column(name = "userid") 
    private Integer id; 
    @Column(name = "username") 
    private String userName; 
    // some more fields 
    @JoinTable(name = "demouserprojbind", joinColumns = { 
     @JoinColumn(name = "username", referencedColumnName = "username") 
    }, inverseJoinColumns = { 
     @JoinColumn(name = "projcode", referencedColumnName = "projcode") 
    }) 
    @ManyToMany 
    private Set<DemoProject> projects; 

DemProject не имеет отображенный ManyToMany для пользователей. Таблица привязки «demouserprojbind» связывается с уникальными (не-нулевыми) текстовыми столбцами вместо последовательных PK.

Демо-код обновления:

DemoUser user = getUser(username); // EntityManager Query by username 
Set<DemoProject> userProjects = user.getProjects(); 
userProjects.clear(); 
EntityManager em = emf.createEntityManager(); 
utx.begin(); 
em.joinTransaction(); 
em.merge(user); 
em.flush(); 
utx.commit(); 
em.close(); 

Это демонстрационный код сделано в Servlet - эдс и UTX и вводили EntityManagerFactory и UserTransaction.

Когда я прослеживать SQL из EclipseLink, это выглядит следующим образом:

DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?)) 
bind => [Project2, null] 
DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?)) 
bind => [Project1, null] 

По-видимому, не в состоянии поставить в имя пользователя-владельца объекта - SQL, не соответствует ни одной строки, и, таким образом, никакие строки не будут удалены из базы данных.

Есть ли что-то, что я делаю неправильно в моей логике сохранения (я хочу удалить привязку между пользователем и проектом, но и сам пользователь и проект), или это ошибка в EcliseLink?

+0

Это единственная вещь, которая не работает, и у вас есть какие-либо настройки на отображение или события на объекте? JPA не позволяет использовать не-pk-поля в отношениях, и хотя он поддерживается большинством провайдеров (EclipseLink позволяет это), он вызывает проблемы с такими вещами, как кеширование и обычно приводит к предупреждениям. Убедитесь, что какое-либо событие не запускается, чтобы установить userName = null или что вы каким-либо образом не модифицировали экземпляр только для чтения, так что запрос для этого имени пользователя возвращает поврежденный объект из кеша. – Chris

ответ

0

В ваших Путах

@ManyToMany 
private Set<DemoProject> projects; 

в ManyToMany на этой заметке каскадного типа, как это:

@ManyToMany(cascade={CascadeType.MERGE, CascadeType.REMOVE }) 
private Set<DemoProject> projects; 
+0

На самом деле у моего демо-кода был «(cascade = CascadeType.ALL)», а настройка на (cascade = {CascadeType.MERGE, CascadeType.REMOVE}) не улучшила ситуацию. – thomjah