我有两个实体,Place 和 PlaceShape。PlaceShape 被标记为惰性的一对一关联,它在 Hibernate 中工作得非常好。但是,当我编辑 Place(不加载 PlaceShape)并提交更改时,Envers 似乎正在加载 PlaceShape 以计算差异。它没有加载任何一对多的集合。这会导致与性能相关的问题,因为 PlaceShape 是一个巨大的实体,需要在特定情况下加载。调用堆栈跟踪、SQL 日志和 Java 代码如下所述。非常感谢任何帮助或建议。
谢谢,
这是获取形状的堆栈跟踪:
Place.getPlaceShape(Place.java:160)
at sun.reflect.GeneratedMethodAccessor361.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:172)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:175)
at org.hibernate.envers.entities.mapper.MultiPropertyMapper.mapToMapFromEntity(MultiPropertyMapper.java:107)
at org.hibernate.envers.synchronization.work.CollectionChangeWorkUnit.generateData(CollectionChangeWorkUnit.java:56)
at org.hibernate.envers.synchronization.work.AbstractAuditWorkUnit.perform(AbstractAuditWorkUnit.java:72)
at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:114)
at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:152)
at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:138)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
以下是上述操作的 SQL 日志:
select place0_.PID as PID1_10_6_, place0_.NAME as NAM2_10_6_ from PLACE place0_ where place0_.PID=?;
update PLACE (NAME) values (?);
select hibernate_sequence.nextval from dual;
select placeshape0_.SPATIAL_ID as SPATIAL1_19_7_, placeshape0_.PID as PID3_19_7_, placeshape0_.SHAPE as SHAPE19_7_, place1_.PID as PID1_10_0_, place1_.NAME as NAM2_10_0_ from PLACE_SHAPE placeshape0_ left outer join PLACE place1_ on placeshape0_.PID=place1_.PID where placeshape0_.PID=?;
insert into Revinfo (log, revtstmp, username, rev) values (?, ?, ?, ?);
insert into PLACE_AUD (REVTYPE, NAME, PID, REV) values (?, ?, ?, ?);
这是实体的代码:
@Entity
@Audited
@Table(name = "PLACE")
public class Place implements FieldHandled {
private long pid;
private String name;
private PlaceShape placeShape;
private FieldHandler fieldHandler;
@Id
@Column(name = "PID", columnDefinition = "NUMBER(10,0)", nullable = false)
public long getPid() {
return pid;
}
public void setPid(long pid) {
this.pid = pid;
}
@Column(name = "NAME", columnDefinition = "NVARCHAR(100)", nullable = true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToOne(mappedBy = "place", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, optional = true)
@LazyToOne(value = LazyToOneOption.NO_PROXY)
public PlaceShape getPlaceShape() {
if (fieldHandler != null) {
return (PlaceShape) fieldHandler.readObject(this, "placeShape", placeShape);
}
return placeShape;
}
public void setPlaceShape(PlaceShape placeShape) {
if (fieldHandler != null) {
this.placeShape = (PlaceShape) fieldHandler.writeObject(this, "placeShape", this.placeShape, placeShape);
return;
}
this.placeShape = placeShape;
}
}
@Audited
@Entity
@Table(name = "PLACE_SHAPE")
public class PlaceShape implements Serializable {
private long id;
private Place place;
private Geometry shape;
@Id
@SequenceGenerator(name = "SEQ_STORE", sequenceName = "SPATIAL_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STORE")
@Column(name = "SPATIAL_ID", columnDefinition = "NUMBER(10, 0)", nullable = false)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PID", referencedColumnName = "PID")
public Place getPlace() {
return place;
}
public void setPlace(Place place) {
this.place = place;
}
@Type(type = "org.hibernatespatial.GeometryUserType")
@Column(name = "SHAPE", columnDefinition = "MDSYS.SDO_GEOMETRY", nullable = false)
public Geometry getShape() {
return shape;
}
public void setShape(Geometry shape) {
this.shape = shape;
}
}