Как вставить запись в таблицу соединений аннотации гибернации «многие ко многим»? - PullRequest
5 голосов
/ 09 мая 2009

У меня есть много ко многим отношениям между двумя таблицами и создание новой таблицы соединений в спящем режиме Теперь, как я могу вставить запись в таблицу соединений путем обновления обеих таблиц скажем, две таблицы: tbluser и tbldomain

Я должен вставить запись в tbluserdomainrelation с обеих сторон (то есть из tbluser и tbldomain)

В настоящее время я могу вставить запись в таблицу соединений только когда сохраняю или обновляю tbluser, но хочу запись, которая будет вставлена, когда я обновляю отношения в доменной таблице также

В user.class Я написал

@ManyToMany(targetEntity = VirtualDomain.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER)

@JoinTable(name = "tblUserDomainRel", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "domainid"))

public Set<VirtualDomain> getVirtualdomainset() {
        return virtualdomainset;
}

public void setVirtualdomainset(Set<VirtualDomain> virtualdomainset) {
        this.virtualdomainset = virtualdomainset;
}

Пока в доменной таблице у меня есть запись

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER, mappedBy = "virtualdomainset", targetEntity = User.class)

public Set<User> getUserset() {
        return userset;
}

public void setUserset(Set<User> userset) {
        this.userset = userset;
}

Ответы [ 3 ]

9 голосов
/ 04 июня 2009

Я подозреваю, что вы можете упасть на первое препятствие:

Как было сказано ранее, Hibernate обновит объект, который вы называете update(), и затем перейдет к любым последующим объектам, требующим обновления, в соответствии с правилами, указанными в атрибуте @Cascade.

Проблема в том, что ваш класс User владеет отношением, и добавление объекта User в коллекцию VirtualDomain.userset никак не изменяет объект User. Таким образом, даже с каскадом Hibernate не будет обновлять объект User, так как не считает, что должен.

Вместо этого при добавлении объекта в коллекцию VirtualDomain.userset убедитесь, что VirtualDomain также добавлен в коллекцию User.virtualdomainset.

// given a VirtualDomain object
VirtualDomain domain = getSession().load( VirtualDomain.class, 1234 );

// and a User object
User user = getSession().load( User.class, 5678 );

// add the User to the VirtualDomain
domain.getUserset().add( user );
// but also add the VirtualDomain to the user
user.getVirtualdomainset().add( domain );

// update the VirtualDomain and the Cascade settings will also update the User
getSession().update( domain );

В подобных случаях я считаю полезным предоставить вспомогательный метод для добавления объектов в коллекции, а не использовать прямой доступ к самим коллекциям. например, * 1 020 *

public class VirtualDomain {

    Set userset;

   /* snip... */

    public void addUser( User user ) {
        getUserset().add( user );
        user.getVirtualdomainset().add( this );
    }
}

Хотя стоит помнить совет предков Hibernate:

"В реальной системе у вас может не быть связи" многие ко многим ". Наш опыт показывает, что почти всегда есть другая информация, которая должна быть прикреплена к каждой ссылке ... лучший способ ... это через промежуточный ассоциативный класс . " (Java Persistence With Hibernate, стр. 297/298, ISBN 1-932394-88-5)

0 голосов
/ 11 мая 2009

Вы сделали класс User владельцем отношений. Если вы хотите пойти другим путем, вам нужно переключить их отображение, чтобы Domaintable имел @JoinTable. Или вам нужно вручную принудительно вызвать его с помощью @PrePersist или @PreUpdate на Domaintable, чтобы принудительно вызвать обновление для пользователя, который вставит строку в таблицу соединения. Я уверен, что есть и другие способы сделать это, но вот те два, которые приходят на ум.

@PreUpdate example :

@EntityListeners( Domaintable.class )
@Entity
public class Domaintable
{

User  user;

....

@PreUpdate
public void onPreUpdate( DomainTable domainTable )
{
   if( domainTable.getUser() != null )
   {
       entitymanager.update( domainTable.getUser() );
    }
}

....

}
0 голосов
/ 09 мая 2009

Как выглядят ваши уроки?

Полагаю, у вас есть класс Domain и класс User. Предположим, что в классе Domain у вас есть коллекция Users. Добавьте объект User в коллекцию Users и вызовите SaveOrUpdate для объекта Domain. Также убедитесь, что вы указали правильную опцию каскадирования (например, cascading = "save-update".

Это немного большая картина. Нам нужна более подробная информация о том, что не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...