4

我有:

@Entity
public class EmailAndName {
...
}

@Entity
public class MessageDetails {
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "MessageDetails_to")
    public Set<EmailAndName> getTo() {
        return to;
    }
}

当我

public static void main(String []a)
{
    StatelessSession sess = HibernateUtils.getSessionFactory().openStatelessSession();
    sess.beginTransaction();
    MessageDetails messageDetails = new MessageDetails();
    messageDetails.setTo(new HashSet<EmailAndName>());
    EmailAndName emailAndName = (EmailAndName) sess.get(EmailAndName.class, 1L);
    if (emailAndName == null ) throw new RuntimeException();
    messageDetails.getTo().add(emailAndName);
    sess.insert(messageDetails);
    sess.getTransaction().commit();
}

未填充 MessageDetails_to 表。我应该怎么办?我不想编写本机查询。谢谢你。

4

3 回答 3

5

您还没有通读hibernate-doc的无状态会话

它明确指出:

Operations performed using a stateless session never cascade to associated instances. Collections are ignored by a stateless session.

你正在尝试添加一个Set<EmailAndName>. 无状态会话是一种较低级别的抽象,更接近底层的 JDBC。所以如果你真的想让你的代码工作并填充 MessageDetails_to.. 你需要去 Session。您将需要为您的 POJO 定义 equals 和 hashCode 方法:)

所以您修改后的代码将是:

public static void main(String []a)
{
   try{
    Session sess = HibernateUtils.getSessionFactory().openSession();
    sess.beginTransaction();
    MessageDetails messageDetails = new MessageDetails();
    messageDetails.setTo(new HashSet<EmailAndName>());
    EmailAndName emailAndName = (EmailAndName) sess.get(EmailAndName.class, 1L);
    if (emailAndName == null ) throw new RuntimeException();
    messageDetails.getTo().add(emailAndName);
    sess.save(messageDetails);
    sess.getTransaction().commit();
 }
catch(HibernateException e)
 {
   sess.getTransaction.rollback();
   e.printStackTrace();
 }
  finally{
       sess.close();
  }

您必须始终包含一个 try catch,以便您可以识别异常(如果有)并使其工作:)

于 2012-12-19T08:41:19.300 回答
0

First, are you sure that the transaction is commited?

Second, you are using a Set. Do you have sure that the equals and hashCode method of the EmailAndName class are well-defined?

于 2012-12-14T19:22:03.713 回答
0

好吧,我认为您的代码无法正常工作的主要原因是由于使用了无状态会话,但无论如何我建议您在实现 1-N 和 NM 关系时定义关系的反面并更新双方。

另外,不要让外部类直接操作集合,因为它破坏了封装。不要为您的集合公开 set 方法,这可能会导致难以调试的非常讨厌的异常。使用添加删除方法来更新您的集合。

@Entity
public class MessageDetails {

    private Set<EmailAndName> to = new HashSet<EmailAndName>();

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "MessageDetails_to", 
       joinColumns = {@JoinColumn(name = "MESSAGE_DETAILS_ID"},
       inverseJoinColumns = {@JoinColumn(name = "EMAIL_AND_ADDRESS_ID")})
    public Set<EmailAndName> getTo() {
        return Collections.unmodifiableSet(to);
    }

    public void addEmaiAndName(EmailAndName emailAndName) {
       emailAndName.setMessageDetails(this);
       to.add(emailAndName);
    }

    public void removeEmailAndName(EmailAndName emailAndName) {
       emailAndName.setMessageDetails(null);
       to.remove(emailAndName);
    }

}

代码的另一部分应该是这样的:

Session sess = HibernateUtils.getSessionFactory().openSession();
sess.beginTransaction();
MessageDetails messageDetails = new MessageDetails();
EmailAndName emailAndName = (EmailAndName) sess.get(EmailAndName.class, 1L);
if (emailAndName == null ) throw new RuntimeException();
messageDetails.addEmailAndName(emailAndName);
sess.save(messageDetails);
sess.getTransaction().commit();
于 2012-12-22T00:05:20.930 回答