2014-12-04 69 views
1

我有形式,其中我決定選擇字段像OrganizationalCell:當我選擇一個選項FE:OrganizationalCellUnit,我不得不atach與實體OrganizationalCellUnit,另一個輸入端僅在該配置中是必需的。JPA /休眠@ManyToOne把零誤差:org.hibernate.TransientPropertyValueException:

當我選擇其他值時,這個值不再是(OrganizationalCellUnit)。

我有我的實體,我想堅持:

@ManyToOne(cascade = CascadeType.MERGE) 
public OrganizationalCell organizationalCell; 

@ManyToOne(cascade = CascadeType.MERGE) 
@Nullable 
public OutPatientClinic outPatientClinic; 

@ManyToOne(cascade = CascadeType.MERGE) 
@Nullable 
public Workshop workshop; 

@ManyToOne(cascade = CascadeType.MERGE) 
public OrganizationalCellUnit organizationalCellUnit = null; 

/** The clinic. */ 
@ManyToOne(cascade = CascadeType.MERGE) 
public models.Clinic clinic; 

/** The unit. */ 
@ManyToOne(cascade = CascadeType.MERGE) 
public models.Unit unit; 

而且我得到一個錯誤:

Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: models.MedicalIncident.organizationalCellUnit -> models.OrganizationalCellUnit 

在DB這些領域允許nullabe值。

如何使這個領域不是強制性的,並把休眠空值在DB

---更新---- CascadeType的更新到所有對多對一的關係後,我有這樣的錯誤:

play.api.Application$$anon$1: Execution exception[[ConstraintViolationException: Validation failed for classes [models.OrganizationalCellUnit] during persist time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=updateUser, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=name, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=creationUser, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
]]] 
     at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10-2.2.4.jar:2.2.4] 
     at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10-2.2.4.jar:2.2.4] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.4.jar:2.2.4] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.4.jar:2.2.4] 
     at scala.Option.map(Option.scala:145) [scala-library.jar:na] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10-2.2.4.jar:2.2.4] 
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [models.OrganizationalCellUnit] during persist time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=updateUser, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=name, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
     ConstraintViolationImpl{interpolatedMessage='error.required', propertyPath=creationUser, rootBeanClass=class models.OrganizationalCellUnit, messageTemplate='error.required'} 
] 
     at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 
     at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 
     at org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:178) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 
     at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:75) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 
     at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 
     at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:203) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1] 

---編輯新增

public class OrganizationalCellUnit extends GenericDictionary<OrganizationalCellUnit> {} 

@MappedSuperclass 
public abstract class GenericDictionary<T extends Generic<T>> extends Generic<T> { 

    @Required 
    public String name; 
    @Required 
    public boolean active = true; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public boolean getActive() { 
     return active; 
    } 

    public void setActive(boolean stat) { 
     this.active = stat; 
    } 
    /** 
    * Options. 
    * 
    * @return the map 
    */ 
    public Map<String, String> getOptions() { 
     return getOptions(getList()); 
    } 
    public Map<String, String> getOptions(List<T> list) { 
     LinkedHashMap<String, String> options = new LinkedHashMap<String, String>(); 
     for (T e : list) { 
      GenericDictionary<?> entity = (GenericDictionary<?>) e; 
      if(entity.active==true) { 
       options.put(e.id.toString(), entity.name); 
      } 
     } 
     return options; 
    } 

    public void on() { 
     this.active = true; 
     update();  
    } 

    public void off() { 
     this.active = false; 
     update();  
    } 
    public abstract String getFieldDescription(String name); 
    @Override 
    public boolean equals(Object other) { 
     if (other == null) return false; 
     if (other == this) return true; 
     if (!(other instanceof GenericDictionary))return false; 
     GenericDictionary<?> otherMyClass = (GenericDictionary<?>) other; 
     return name.equals(otherMyClass.name); 
    } 

@MappedSuperclass 
public abstract class Generic<T extends Generic> { 
    @Transient 
    public Class<T> entityClass; 
    Generic() { 
     entityClass = ((Class) ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0])); 
    } 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    public Long id; 

    @ManyToOne(cascade = CascadeType.MERGE) 
    @Constraints.Required 
    public User creationUser; 
    @ManyToOne(cascade = CascadeType.MERGE) 
    @Constraints.Required 
    public User updateUser; 
    @Constraints.Required 
    public String creationDate = Index.getDate(null); 
    @Constraints.Required 
    public String updateDate = Index.getDate(null); 

    public User getCreationUser() {return creationUser;} 
    public void setCreationUser(User user) {this.creationUser = user;} 
    public void setCreationUser() {this.creationUser = User.getCurrentUser();} 
    public User getUpdateUser() {return updateUser;} 
    public void setUpdateUser(User user) {this.updateUser = user;} 
    public void setUpdateUser() {this.updateUser = User.getCurrentUser();} 
    public String getCreationDate() {return creationDate;} 
    public void setCreationDate(String creationDate) {this.creationDate = creationDate;} 
    public String getUpdateDate() {return updateDate;} 
    public void setUpdateDate(String updateDate) {this.updateDate = updateDate;} 
    public T getBy(Long id) { 
     return JPA.em().find(entityClass, id); 
    } 
    public List<T> getList() { 
     return (List<T>) JPA.em().createQuery("FROM " + entityClass.getSimpleName()).getResultList(); 
    } 

    public List<T> getByUser_id(Long id) { 
     List<T> entities = new ArrayList<T>(); 
     TypedQuery<T> query = JPA.em().createQuery("SELECT r FROM " + entityClass.getSimpleName() + " r WHERE r.user.id != :user_id", entityClass).setParameter("user_id", id); 
     try { 
      entities = query.getResultList(); 
     } catch (NoResultException e) { 
      entities = null; 
     } 
     return entities; 
    } 

    public List<T> getByParameterAndValue(String parameter, String value) { 
     List<T> entities = new ArrayList<T>(); 
     String sqlString = "SELECT e FROM " + entityClass.getSimpleName() + " e WHERE e."+ parameter +" != :value"; 
     TypedQuery<T> query = JPA.em().createQuery(sqlString, entityClass).setParameter("value", value); 
     try { 
      entities = query.getResultList(); 
     } catch (NoResultException e1) { 
      entities = null; 
     } catch (Exception e) { 
      Index.toLog("error","Unsupported error in Generic model class in " + entityClass); 
     } 
     return entities; 
    } 



    @PrePersist 
    public void prePersist() { 
     Logger.warn(this.toString()); 
     setCreationDate(Index.getDate(null)); 
     preUpdate(); 
    } 

    @PreUpdate 
    public void preUpdate() { 
     Logger.debug(this.toString()); 
     setUpdateDate(Index.getDate(null)); 
    } 
    public void toDataBase() { 
     System.out.println("------------------Trying to persist------------------------"); 
     JPA.em().persist(this); 
    } 
    public void update() { 
     JPA.em().merge(this); 
    } 
    public void delete() { 
     JPA.em().remove(this); 
    } 

    /** 
    * A Generic toString method that can be used in any class. 
    * uses reflection to dynamically print java class field 
    * values one line at a time. 
    * requires the Apache Commons ToStringBuilder class. 
    */ 
    public String toString() { 
     return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); 
    } 
// @Override 
// public int hashCode() { 
//  return id.hashCode(); 
// } 


} 

回答

0

而不是

@ManyToOne(cascade = CascadeType.MERGE) 
public OrganizationalCellUnit organizationalCellUnit = null; 

使用此

@ManyToOne(cascade = CascadeType.ALL) 
public OrganizationalCellUnit organizationalCellUnit; 
+0

確定。它的工作,我沒有這個錯誤了。現在是驗證問題:'play.api.Application $$ anon $ 1:執行異常[[ConstraintViolationException:對於組[java.value.groups]的持久化時間類[models.OrganizationalCellUnit]的驗證失敗。默認,] '我更新了新的堆棧跟蹤文章 – masterdany88 2014-12-04 12:58:01

+0

您可以發佈OrganizationalCellUnit.java代碼嗎? – Pracede 2014-12-04 13:18:24

+0

這很複雜。它擴展了泛型。完成 – masterdany88 2014-12-04 13:30:21

1

我有同樣的問題,而且它變成了(至少在我的情況),這是遊戲的錯 - 我也可以使用Play來看你。

ModelObject object = form.get() 

即使organizationalCell場不是從形式傳遞,真正發揮(在你的案件類型OrganizationalCellUnit的)創建了一個虛擬模型對象。所以object.organizationalCell不是null。如果您嘗試調用

object.save() 

是什麼讓這個令人難以置信的很難發現是,

object.organizationalCell.toString() 

實際上會寫出「空」 JPA然後理所當然地大喊。

解決辦法:

​​3210