我目前在将对象写入数据库时遇到一些麻烦。我的问题的确出现在一个非常复杂的数据模型中,但是我将尝试将其分解为一个可以理解的示例。
假设有一个课程 A :
searchHandler(event) {
let keyword = event.target.value;
clearTimeout(this.typingTimer);
this.typingTimer=setTimeout(()=>{
let filter= {
"where": {
"or": [
{
"companyName":{"regexp":keyword +"/i"}
},
{
"primaryPhone":{"regexp":keyword +"/i"}
},
{
"emailAddress":{"regexp":keyword +"/i"}
},
{
"venueCode":{"regexp":keyword +"/i"}
},
{
"website":{"regexp":keyword +"/i"}
},
]
}
}
this.props.getParties(filter);
let filtered = this.state.data.filter(item => {
return (
item.companyName.toLowerCase().indexOf(keyword) > -1 ||
item.primaryPhone.toLowerCase().indexOf(keyword) > -1 ||
item.emailAddress.toLowerCase().indexOf(keyword) > -1 ||
item.venueCode.toLowerCase().indexOf(keyword) > -1 ||
item.website.toLowerCase().indexOf(keyword) > -1 ||
item.description.toLowerCase().indexOf(keyword) > -1
);
});
if (keyword === "") {
filtered = [];
this.getData();
}
this.setState({
filtered,
});
const { skip } = this.state;
if(this.state.filtered.length>0 || !this.state.filtered.length){
this.setState({
filtered:[],
skip: skip - skipDecrement
})
}
},550)
}
所引用的类 B 非常简单:它仅包含@Entity(name = "a")
@Table(schema = "foo")
public class A {
private static final long serialVersionUID = -5305374150112492804L;
logger = LoggerFactory.getLogger(A.class);
@Id
@Column(name = "tid", nullable = false, unique = true)
@SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
private Integer TID;
@Column(name = "b")
private String bId;
@OneToMany(targetEntity = B.class)
@JoinColumn(name = "random_b_attribute", referencedColumnName = "b", updatable = false, insertable = false)
private List<B> b;
@PrePersist
@PreUpdate
public void prePersist() {
bId = b == null || b.isEmpty() ? null : b.get(0).getRandomAttribute();
}
...
}
带注释的属性。请注意, A 实例可以并且将在其属性@Column
中引用 B 的相同“集合”。
引用 A 的是第三类 D :
b
出现问题:
@Entity(name = "d")
@Table(schema = "foo")
public class D {
private static final long serialVersionUID = -5305374150112492804L;
logger = LoggerFactory.getLogger(D.class);
@Id
@Column(name = "tid", nullable = false, unique = true)
@SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
private Integer TID;
@Column(name = "a")
private Integer aId;
@ManyToOne(targetEntity = A.class)
@JoinColumn(name = "a", referencedColumnName = "tid", updatable = false, insertable = false)
private A a;
@PrePersist
@PreUpdate
public void prePersist() {
aId = a == null ? null : a.getTID();
}
...
}
从数据库中检索了 A 的所有对象,稍后我希望将它们插入 D 实例中(也是惰性的)。 EntityManager
或D#a
属性。A#b
任何新创建的 D 实例最终会导致以下异常:EntityManager#persist
在研究过程中,我发现提供相同的Caused by: org.hibernate.HibernateException: Found shared references to a collection: random.package.structure.A.b
时可能会引起错误(不要与具有相同条目的Collection
混淆)。显然,这是由jpa本身对 A 实例的初始化造成的吗?回收一个相同的Collection
似乎是一个好主意,但显然在更新未更改的对象时会引起问题...
在持久保存对象之前清除Collection
似乎可以解决问题。但是,由于以后使用这些对象将所有内容懒惰地读取,将导致其他问题。
您是否有关于如何为每个 A 实例创建新的EntityManager
或以其他方式防止失败的提示?
在此先感谢您,如果我确实错过了任何信息,请问一下!
答案 0 :(得分:0)
非常感谢您的回答! @crizzis的提示可以解决问题。
当然是@ManyToMany
关系。我更改了数据模型(以使用映射表),这解决了我的问题!