Java spring-hibernate-org.hibernate.transientObject异常:对象引用未保存的临时实例
我有一个主表Java spring-hibernate-org.hibernate.transientObject异常:对象引用未保存的临时实例,java,mysql,database,spring,hibernate,Java,Mysql,Database,Spring,Hibernate,我有一个主表和一个表卡片,它们之间有一对一的关系。在添加卡时我会下拉选择一张blend,卡上有一列blend\u id 在添加卡时我想将卡保存在表中,其混合id值等于从下拉列表中选择的混合id 我使用的是spring hibernate,这是我在提交卡片表单时遇到的例外情况: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient in
和一个表卡片,它们之间有一对一的关系。在添加卡时
我会下拉选择一张blend
,卡上有一列blend\u id
在添加卡时
我想将卡
保存在表中,其混合id
值等于从下拉列表中选择的混合id
我使用的是spring hibernate,这是我在提交卡片表单时遇到的例外情况:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.terp.entity.BlendEntity
org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243)
org.hibernate.type.EntityType.getIdentifier(EntityType.java:456)
org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265)
org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275)
org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295)
org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3403)
org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520)
org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230)
org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154)
org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy26.addCard(Unknown Source)
com.terp.controller.CardController.addCard(CardController.java:122)
com.terp.controller.CardController$$FastClassByCGLIB$$43e17ccc.invoke(<generated>)
net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:617)
com.terp.controller.CardController$$EnhancerByCGLIB$$4627162d_2.addCard(<generated>)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:427)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:788)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:717)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
CardEntity.java
package com.terp.entity;
import java.util.Date;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Proxy;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import org.springframework.transaction.annotation.Transactional;
@Entity
@Table(name="cards")
@Proxy(lazy=false)
public class CardEntity {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne
@JoinColumn(name="division_id", referencedColumnName="id")
private DivisionEntity division;
private Integer card_series;
private String card_number;
private Integer shade;
@OneToOne
@JoinColumn(name="unit_of_qty_id", referencedColumnName="id")
private UnitEntity unit;
private Date card_date;
private Date issue_date;
private String cutomer_ref;
private String hl_number;
private String design_number;
@OneToOne
@JoinColumn(name="designWay_id", referencedColumnName="id")
private DesignWayEntity designWay;
/* @OneToOne
@JoinColumn(name="dyeingType_id", referencedColumnName="id")
private DyeingTypeEntity dyeingType;*/
private String dyeingType;
private Integer total_days;
private Date order_date;
private Date grey_date;
private Date target_date;
@OneToOne
@JoinColumn(name="qualityBase_id", referencedColumnName="id")
private QualityBaseEntity qualityBase;
@OneToOne
@JoinColumn(name="openFor_id", referencedColumnName="id")
private OpenForEntity openFor;
@OneToOne
@JoinColumn(name="width_id", referencedColumnName="id")
private WidthEntity width;
@OneToOne
@JoinColumn(name="finishType_id", referencedColumnName="id")
private FinishTypeEntity finishType;
@OneToOne
@JoinColumn(name="blend_id", referencedColumnName="id")
private BlendEntity blend;
private Float weight;
@OneToOne
@JoinColumn(name="merchant_id", referencedColumnName="id")
private MerchantEntity merchant;
@OneToOne
@JoinColumn(name="priority_id", referencedColumnName="id")
private PriorityEntity priority;
@OneToMany(fetch = FetchType.EAGER, mappedBy="card", cascade = CascadeType.ALL)
@Sort(type=SortType.NATURAL)
private SortedSet<ShadeEntity> shades = new TreeSet<ShadeEntity>();
private Float total_qty;
@Transactional
public SortedSet<ShadeEntity> getShades() {
return shades;
}
@Transactional
public void setShades(SortedSet<ShadeEntity> shades) {
this.shades = shades;
}
@Temporal(TemporalType.TIMESTAMP)
private Date created_at;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public DivisionEntity getDivision() {
return division;
}
public void setDivision(DivisionEntity division) {
this.division = division;
}
public Integer getCard_series() {
return card_series;
}
public void setCard_series(Integer card_series) {
this.card_series = card_series;
}
public String getCard_number() {
return card_number;
}
public void setCard_number(String card_number) {
this.card_number = card_number;
}
public Integer getShade() {
return shade;
}
public void setShade(Integer shade) {
this.shade = shade;
}
public UnitEntity getUnit() {
return unit;
}
public void setUnit(UnitEntity unit) {
this.unit = unit;
}
public Date getCard_date() {
return card_date;
}
public void setCard_date(Date card_date) {
this.card_date = card_date;
}
public String getCutomer_ref() {
return cutomer_ref;
}
public void setCutomer_ref(String cutomer_ref) {
this.cutomer_ref = cutomer_ref;
}
public String getHl_number() {
return hl_number;
}
public void setHl_number(String hl_number) {
this.hl_number = hl_number;
}
public String getDesign_number() {
return design_number;
}
public void setDesign_number(String design_number) {
this.design_number = design_number;
}
public DesignWayEntity getDesignWay() {
return designWay;
}
public void setDesignWay(DesignWayEntity designWay) {
this.designWay = designWay;
}
public String getDyeingType() {
return dyeingType;
}
public void setDyeingType(String dyeingType) {
this.dyeingType = dyeingType;
}
public Date getOrder_date() {
return order_date;
}
public void setOrder_date(Date order_date) {
this.order_date = order_date;
}
public Date getGrey_date() {
return grey_date;
}
public void setGrey_date(Date grey_date) {
this.grey_date = grey_date;
}
public Date getTarget_date() {
return target_date;
}
public void setTarget_date(Date target_date) {
this.target_date = target_date;
}
public QualityBaseEntity getQualityBase() {
return qualityBase;
}
public void setQualityBase(QualityBaseEntity qualityBase) {
this.qualityBase = qualityBase;
}
public OpenForEntity getOpenFor() {
return openFor;
}
public void setOpenFor(OpenForEntity openFor) {
this.openFor = openFor;
}
public WidthEntity getWidth() {
return width;
}
public void setWidth(WidthEntity width) {
this.width = width;
}
public FinishTypeEntity getFinishType() {
return finishType;
}
public void setFinishType(FinishTypeEntity finishType) {
this.finishType = finishType;
}
public BlendEntity getBlend() {
return blend;
}
public void setBlend(BlendEntity blend) {
this.blend = blend;
}
public Float getWeight() {
return weight;
}
public void setWeight(Float weight) {
this.weight = weight;
}
public Integer getTotal_days() {
return total_days;
}
public void setTotal_days(Integer total_days) {
this.total_days = total_days;
}
public MerchantEntity getMerchant() {
return merchant;
}
public void setMerchant(MerchantEntity merchant) {
this.merchant = merchant;
}
public PriorityEntity getPriority() {
return priority;
}
public void setPriority(PriorityEntity priority) {
this.priority = priority;
}
public Float getTotal_qty() {
return total_qty;
}
public void setTotal_qty(Float total_qty) {
this.total_qty = total_qty;
}
public Date getCreated_at() {
return created_at;
}
public void setCreated_at(Date created_at) {
this.created_at = created_at;
}
public Date getIssue_date() {
return issue_date;
}
public void setIssue_date(Date issue_date) {
this.issue_date = issue_date;
}
}
在卡片中,如果我添加级联,它将在混合中添加新行:
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="blend_id", referencedColumnName="id")
private BlendEntity blend;
您有持久性上下文问题。看见未保存的临时实例不在持久性上下文中
javadoc:
当用户将临时实例传递给会话方法时引发
这需要一个持久实例
两种可能的解决办法:
>p>如果关系真的是代码> @ OnOutON/CODE >,考虑重构
通过在卡片表中定义混合列来创建架构。和都默认为true。但是,@OneToOne
关系的目的是目标实体(行)不被多个引用实体共享。允许空混合外键意味着许多混合可以不被任何卡共享
不要将@Transactional
放在实体方法上。是在服务(可能还有Dao)层上定义@Transactional
。另外,检查您的服务/Dao/存储库配置和代码,确保这两个实体由相同的持久性上下文管理,例如,通过find()
ing混合ID引用的先前持久化混合实体,然后将其分配给卡。为了更好地理解实体、实体管理器、持久性上下文和事务是如何交互的,我从中略去了以下要点。我与作者无关
- Dao/存储库层必须使用JPA EntityManager进行持久化
- 实体管理器管理持久性上下文,即一组持久性实体实例
- 持久实体既有内存中的对象标识,也有由(主键)唯一标识的数据库表示(行)定义的数据库标识
- 无论应用程序是否设置了实体的“唯一标识”字段,临时实体都没有数据库表示形式
- Java内存模型不是事务性的。分离(或暂时)对象实体的状态不会自动与DB同步
- 如果持久性上下文参与事务,则托管实体的内存中状态将与数据库同步
- 分离(暂时)实体不能与任何需要托管实例的实体管理器操作一起使用。
- 实体管理器类型决定持久性上下文的生存期
- JPA定义了3种类型的实体管理器,每种类型都需要不同的持久性上下文管理:
- 容器管理的实体管理器:
- 事务范围:
@PersistenceContext
//默认为type=PersistenceContextType.TRANSACTION
- 使用事务作为跟踪/传播持久性上下文的方式
- 无国籍;它可以安全地存储在任何JavaEE组件上
- 容器代理持久性提供程序的实体管理器以管理其生命周期
- 当应用程序调用实体管理器方法时,容器的实体管理器代理将检查现有的持久性上下文
与当前事务关联。如果代理找到一个,实体管理器将使用现有的持久性上下文。如果
如果找不到,代理将创建一个新的持久性上下文并将其与事务关联李>
- 当事务结束时,持久性上下文“消失”,上下文管理的所有实体都分离
- 同一事务中的所有容器管理实体管理器必须共享相同的传播持久性上下文
- 扩展范围:
@PersistenceContext(type=PersistenceContextType.EXTENDED)
- 单个持久性上下文,其作用域为有状态会话bean的生命周期,可能跨越多个事务
- 防止单个事务结束时实体分离
- 应用程序管理的实体管理器:
- 应用程序管理实体管理器的生命周期;必须调用
close()
李>
- 创建自己的私有持久性上下文,该上下文将一直持续到实体管理器关闭为止
- 如果在事务处于活动状态时创建,则自动与事务同步;不然就不行了
- Java SE中提供:
EntityManager工厂。createEntityManager()
- Java EE中提供:
@PersistenceUnit
- 支持不带容器的单元测试
- 应用程序必须显式关闭
EntityManagerFactory
实例。JavaEE容器将自动关闭工厂
- 只能为资源本地事务配置的实体管理器类型
- 可以使用JTA或资源本地XA
似乎分配给卡的BlendEntity没有有效的id,因此hibernate正在blend中将其保存为新行(在测试中使用级联类型)。检查如何将混合设置为卡实体。BlendEntity
不是必填字段,因此如果我没有从下拉列表中选择任何内容进行混合,则卡对象中的BlendEntity
具有所有空字段,包括id
,并且BlendEntity
表中没有带空id
的行,因此这可能是错误的
CONSTRAINT `fk_40` FOREIGN KEY (`blend_id`) REFERENCES `blends` (`id`),
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="blend_id", referencedColumnName="id")
private BlendEntity blend;