Java 冬眠';我只是想要一份非托管副本
我有一个Java应用程序使用Spring,Hibernate使用JPA2.0规范 我试图在for循环中持久化100个“节点”。当我在for循环中前进时,我会持久化每个节点,有时我会得到一些我已经持久化的节点,看看我是否希望我的新节点是其中一个节点的浅克隆,除了它的坐标。(基本上我是在做地图,有时我希望我的方块彼此相同。) 不过,我一直遇到一些问题,并不是所有我想要持久化的问题都被持久化了,而是hibernate/JPA把我搞砸了 整个事情发生在一次交易中Java 冬眠';我只是想要一份非托管副本,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有一个Java应用程序使用Spring,Hibernate使用JPA2.0规范 我试图在for循环中持久化100个“节点”。当我在for循环中前进时,我会持久化每个节点,有时我会得到一些我已经持久化的节点,看看我是否希望我的新节点是其中一个节点的浅克隆,除了它的坐标。(基本上我是在做地图,有时我希望我的方块彼此相同。) 不过,我一直遇到一些问题,并不是所有我想要持久化的问题都被持久化了,而是hibernate/JPA把我搞砸了 整个事情发生在一次交易中 int startingX = sn.g
int startingX = sn.getxCoor() * 10;
int startingY = sn.getyCoor() * 10;
for (int nodeX = startingX; nodeX < startingX + 10; nodeX++) {
for (int nodeY = startingY; nodeY < startingY + 10; nodeY++) {
ns.persistNodeIfNotExistent(this.generateNode(nodeX, nodeY, sn));
}
}
public void persistNodeIfNotExistent(Node toPersist) {
if (nd.getNode(toPersist.getxCoor(), toPersist.getyCoor()) == null) {
nd.merge(toPersist);
}
}
public Node generateNode(int nodeX, int nodeY, SuperNode sn) {
Node newNode = nodeIsDuplicate(nodeX, nodeY);
if (newNode == null) {
newNode = new Node();
[bunch of irrelevant stuff gets set]
}
newNode.setxCoor(nodeX);
newNode.setyCoor(nodeY);
return newNode;
}
public Node nodeIsDuplicate(int nodeX, int nodeY) {
Node nodeToReturn = null;
List<Node> adjacentNodes = ns.getAdjacentNodes(nodeX, nodeY);
int chanceItsDuplicate = 20 * adjacentNodes.size();
if (randomizer.randomInt99() < chanceItsDuplicate) {
Node adjNode = adjacentNodes
.get(randomizer.getRandom().nextInt(adjacentNodes.size()));
ns.detach(adjNode);
nodeToReturn = new Node();
BeanUtils.copyProperties(adjNode, nodeToReturn);
}
return nodeToReturn;
}
int startingX=sn.getxCoor()*10;
int startingY=sn.getyCoor()*10;
对于(int nodeX=startingX;nodeX
我修复这一混乱局面的第一个策略是使用Spring的BeanUtils来复制属性,我认为这会给我一个非托管副本,但它们不会都被持久化,所以一定不会。然后,我通过entityManager添加了detach,以确保它已被分离,但在服务层,我仍然可以看到“getNode”方法出现了一系列结果,即使数据库已被清除
有没有一种简单而明智的方法可以复制我的实体而不让Hibernate每次都阻止我?结果证明,我的问题是他们的primarykey,他们的Id,设置为原始节点的主键。当我手动将副本的Id设置为0时,它起作用了。我使用的是MySQL,所以不确定这是否适用于其他数据库,但考虑到java“int”总是有一个默认值0,它应该是0。实体确实有一个ID,它与它的坐标是分开的,并且显然是被分配的,所以这可能是问题的一部分?但是,如果id是自动生成的int,那么在复制时,如果这是一个问题,我将如何将其设为null?没错,在将实体重新附加到会话时,Hibernate通过其主键来确定它是新记录还是旧记录的更新。在非JPA Hibernate中,什么值是由很少需要的参数决定的。默认值被认为是“合理的”,所以我猜它是该类型对于未初始化变量所具有的任何值。(
0
,null
等)