2012-01-12 56 views
1

我有以下實體Hibernate的實體產生怪異的SQL和嘗試保存重複條目

@Entity 
@Table(name="mail_event") 
@Cacheable(false) 
public class MailEvent extends DomainObject { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    private Long id;  

    @JoinTable(name="mail_event_recipients") 
    @ManyToMany(fetch=FetchType.EAGER) 
    private Set<User> recipients = new HashSet<User>(); 

    @Column(length=255) 
    @Basic(optional=false) 
    private String subject; 

    @Column(length=255) 
    @Basic(optional=false) 
    private String fromName; 

    @Column(length=255) 
    @Basic(optional=false) 
    private String fromEmail; 

    @Lob 
    @Basic(optional=false) 
    private String messageBody; 

    /* 
    * Any users that should appear in the reply-to part of the email header are added here 
    */ 
    @JoinTable(name="mail_event_reply_to") 
    @ManyToMany(fetch=FetchType.EAGER) 
    private Set<User> replyTo = new HashSet<User>(); 

    public MailEvent(){} 

    public MailEvent(
        final String subject, 
        final String messageBody, 
        final User recipient, 
        final String fromName, 
        final String fromEmail){ 
     this(subject,messageBody,recipient,fromName,fromEmail,null); 
    } 

    public MailEvent(
        final String subject, 
        final String messageBody, 
        final Collection<User> recipients, 
        final String fromName, 
        final String fromEmail){ 
     this(subject,messageBody,recipients,fromName,fromEmail,null); 
    } 

    public MailEvent(
        final String subject, 
        final String messageBody, 
        final User recipient, 
        final String fromName, 
        final String fromEmail, 
        final Collection<User> replyTo){ 
     this.subject = subject; 
     this.messageBody = messageBody; 
     this.recipients.add(recipient); 
     this.fromName = fromName; 
     this.fromEmail = fromEmail; 
     if(replyTo != null) 
      this.replyTo.addAll(replyTo); 
    } 

    public MailEvent(   
        final String subject, 
        final String messageBody, 
        final Collection<User> recipients, 
        final String fromName, 
        final String fromEmail, 
        final Collection<User> replyTo 
        ){ 
     this.subject = subject; 
     this.messageBody = messageBody; 
     this.recipients.addAll(recipients); 
     this.fromName = fromName; 
     this.fromEmail = fromEmail; 
     if(replyTo != null) 
      this.replyTo.addAll(replyTo);  

    } 

    public Long getId() { 
     return id; 
    } 

    public Set<User> getRecipients() { 
     return recipients; 
    } 

    public void setRecipients(Set<User> recipients) { 
     this.recipients = recipients; 
    } 

    public void setSubject(String subject) { 
     this.subject = subject; 
    } 

    public String getSubject() { 
     return subject; 
    } 

    public String getFromName() { 
     return fromName; 
    } 

    public void setFromName(String fromName) { 
     this.fromName = fromName; 
    } 

    public String getFromEmail() { 
     return fromEmail; 
    } 

    public void setFromEmail(String fromEmail) { 
     this.fromEmail = fromEmail; 
    } 

    public String getMessageBody() { 
     return messageBody; 
    } 

    public void setMessageBody(String messageBody) { 
     this.messageBody = messageBody; 
    } 

    public Set<User> getReplyTo() { 
     return replyTo; 
    } 

    public void setReplyTo(Set<User> replyTo) { 
     this.replyTo = replyTo; 
    } 

    @Override 
    public int hashCode() { 
     final int weight = 31; 
     int result = 17; 

     result = weight * result + ((id == null) ? 0 : (int) (id^(id >>> 32))); 

     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (this.getClass() != obj.getClass()) 
      return false; 

     MailEvent other = (MailEvent) obj; 

     if (id == null) { 
      if (other.id != null) 
       return false; 
     } else if (!id.equals(other.id)) 
      return false; 

     return true; 
    } 



} 

從中休眠產生下表:

爲什麼我得到的索引是相等的?此外,當我試圖挽救這個類的對象,我得到這個異常:

2012 Jan 12 13:18:42,980[ERROR] - RequestCycle - Could not execute JDBC batch update; SQL [insert into mail_event_recipients (mail_event_id, recipients_id) values (?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into mail_event_recipients (mail_event_id, recipients_id) values (?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637) 
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:102) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:471) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
    at $Proxy84.save(Unknown Source) 
    at se.su.dsv.scipro.data.controllers.impl.NotificationControllerImpl.processNotification(NotificationControllerImpl.java:111) 
    at se.su.dsv.scipro.data.controllers.impl.NotificationControllerImpl.notifyConferencePost(NotificationControllerImpl.java:181) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler.invoke(LazyInitProxyFactory.java:414) 
    at org.apache.wicket.proxy.$Proxy1.notifyConferencePost(Unknown Source) 
    at se.su.dsv.scipro.conference.panels.ConferencePanel$SendWallMessageForm$1.onSubmit(ConferencePanel.java:324) 
    at org.apache.wicket.ajax.markup.html.form.AjaxButton$1.onSubmit(AjaxButton.java:101) 
    at org.apache.wicket.ajax.form.AjaxFormSubmitBehavior.onEvent(AjaxFormSubmitBehavior.java:143) 
    at org.apache.wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:177) 
    at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxBehavior.java:302) 
    at org.apache.wicket.request.target.component.listener.BehaviorRequestTarget.processEvents(BehaviorRequestTarget.java:157) 
    at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) 
    at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) 
    at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) 
    at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1436) 
    at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) 
    at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:486) 
    at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:319) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206) 
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137) 
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467) 
    ... 44 more 
Caused by: java.sql.BatchUpdateException: Duplicate entry '11642' for key 'PRIMARY' 
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020) 
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451) 
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) 
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 
    ... 53 more 

這使我相信,休眠試圖使用已在使用的新對象的ID。我怎樣才能解決這個問題?

編輯:問題似乎是由於某種原因,我不允許在mail_event_recipients不止一次輸入相同recipients_id。爲什麼這種限制存在,我該如何擺脫它?

+0

你能在show_sql標誌設置爲true,看看是什麼產生的實際查詢替換HashSet的? – Gaurav 2012-01-12 05:11:11

+0

User實體如何映射以及如何創建User對象,是否實現了equals()方法? – Pokuri 2012-01-12 05:45:01

+0

@TejasArjun:你的意思是當我啓動服務器時,hibernate做的東西的長列表? – fred 2012-01-12 06:01:41

回答

0

不能添加重複的條目,因爲它是一個集

,被Hibernate注射的持久化集合的表現類似HashMap,HashSet的,TreeMap的,TreeSet中或ArrayList中,根據不同的接口類型。

集合類實例具有值類型的通常行爲

你可以用一個ArrayList

+0

http://docs.oracle.com/javaee/5/api/javax/persistence/ManyToMany.html好像我們有衝突的信息這裏。另外,不幸的是,改爲列表並沒有什麼區別,Hibernate仍然創建了相同的表。 – fred 2012-01-12 08:43:27

+0

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html請參閱此鏈接。您的鏈接是關於JPA不休眠 – 2012-01-12 09:40:26

相關問題