问题描述
我在与另一个实体保持具有@OneToOne关系的实体时遇到问题。 我们最近已将Spring 4和Hibernate 4升级到Java 8,因此我确定某些注释或配置已更改。
相关代码
PermitState.java:
@Entity
@Table(schema = "dbo", name = "PermitState")
public class PermitState implements Serializable {
private String oid;
private Permit permit;
private Integer invoiced;
private Integer used;
private Integer ordered;
private String permitId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERMITID")
public Permit getPermit() {
return permit;
}
@Id
@Column(name = "PERMITID", nullable = true, length = 8,insertable = false,updatable = false)
public String getPermitId() {
return permitId;
}
... more getters and setters (irrelevant)
Permit.java:
@Entity
@Table(schema = "dbo")
public class Permit {
private String permitid;
private PermitState permitState;
...some more attributes, irrelevant
@Id
@Column(name = "PERMITID", length = 8)
public String getPermitid() {
return permitid;
}
@OneToOne(mappedBy="permit", cascade=CascadeType.ALL,fetch = FetchType.LAZY)
public PermitState getPermitState() {
return permitState;
}
堆栈跟踪
Caused by: org.hibernate.exception.GenericJDBCException: could not insert: [dao.srs.model.PermitState]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3099)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3521)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:395)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:387)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:303)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1195)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:515)
... 65 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The index 6 is out of range.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:171)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setterGetParam(SQLServerPreparedStatement.java:700)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setValue(SQLServerPreparedStatement.java:709)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setString(SQLServerPreparedStatement.java:1034)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setString(NewProxyPreparedStatement.java:963)
at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:57)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:93)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:284)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:279)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:343)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrateId(AbstractEntityPersister.java:2835)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2804)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3076)
... 78 more
如您所见,PermitState实体既具有与Permit的关系(通过PERMITID,即Permit中的PK),又具有一个称为PermitId的字段,该字段应与连接的Permit的ID关联。 虽然这似乎不起作用,但似乎它试图插入所有6个属性,即使不应将Permit插入数据库中。 我尝试使用@Transient在PermitState中注释Permit,但是随后出现AnnotationException:
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: dao.srs.model.Permit.permitState, referenced property unknown: dao.srs.model.PermitState.permit
任何帮助将不胜感激!
更新只是为了澄清,数据库只有5个字段-OID,PERMITID,INVOICED,USED和ORDERED-这就是为什么我在考虑插入尝试Permit实体的原因。 当我们使用Java 7,Spring 3,hibernate-批注3.3.1.GA和hibernate-entitymanager 3.3.2.GA时,无需修改即可使用完全相同的代码。 现在,我们使用Java 8,Spring 4和Hibernate core + entitymanager + ehcache 4.2.19。
1楼
在我看来,从异常情况来看,您尝试@Transient的同时仍然拥有@OneToOne和@JoinColumn。 这实际上没有任何意义,因为您告诉Hibernate您想自己处理它,并且它也应该处理它。
我也发现这有点让您在PermitState中同时拥有Permit实体和permitId感到困惑。 您告诉它您不想更新permitId,但仍将其用作连接列吗?
我建议删除permitId,仅在PermitState中具有Permit实体。 如果愿意,您仍然可以使用getPermitId方法,但应将其视为集合。
如果所有其他方法都失败,请尝试并记录Hibernate生成的SQL,以查看发生了什么。 也许将其粘贴给我们看看。
2楼
我想我解决了。 我仍然不完全确定为什么会这样,但是确实可以:
我从PermitState.java中删除了PermitId(String属性),而是在PermitState的Permit实体中使用了PermitId。
看起来像这样:
Permit.java:
private String permitid;
private PermitState permitState;
@OneToOne(mappedBy="permit", cascade=CascadeType.ALL,fetch = FetchType.LAZY)
public PermitState getPermitState() {
return permitState;
}
PermitState.java
private Permit permit;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERMITID")
public Permit getPermit() {
return permit;
}
感谢Martin和Bilbo的帮助。