我的表单中有OrganizationalCell
之类的决策选择字段:当我选择一个选项fe:OrganizationalCellUnit
时,我必须使用实体OrganizationalCellUnit
获取另一个输入,这只是强制性的在那个配置中。
当我选择其他值时,这个不再是强制性的(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值。
如何使此字段不是必需的,并使hibernate在db
中放置null值--- ----更新 在将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 :(得分:1)
我遇到了同样的问题,事实证明(至少在我的情况下)这是Play的错 - 我也可以看到你使用Play。
ModelObject object = form.get()
即使 organizationalCell 字段未从表单传递,Play实际上也会创建一个虚拟模型对象(在您的情况下为OrganizationalCellUnit类型)。所以object.organizationalCell不是 null 。如果你试图打电话,JPA会正确地喊叫
object.save()
让人难以置信的是,
object.organizationalCell.toString()
实际上会写出“null”。
解决方案:
ModelObject object = form.get();
if(object.organizationalCell.id == null) object.organizationalCell = null;
object.save();
答案 1 :(得分:0)
而不是
@ManyToOne(cascade = CascadeType.MERGE)
public OrganizationalCellUnit organizationalCellUnit = null;
使用此
@ManyToOne(cascade = CascadeType.ALL)
public OrganizationalCellUnit organizationalCellUnit;