Hibernate的恶作剧 - 我只想要一个非托管的副本

时间:2013-02-09 09:29:27

标签: java spring hibernate jpa

我有一个使用Spring的Java应用程序,以及使用JPA 2.0规范的Hibernate。

我正在尝试在for循环中保留100个“节点”。当我在for循环中取得进展时,我会持久保存每个节点,有时我会得到一些我已经坚持的节点,看看我是否希望我的新节点除了它的坐标之外是其中一个节点的浅层克隆。 (基本上我正在制作地图,有时我希望我的方块彼此相同。)

我遇到的问题并不是所有我想坚持下来的问题都被坚持下去了,而且它是hibernate / JPA搞砸了我。

整个事情发生在一次交易中。

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;
}

我解决这个问题的第一个策略是使用Spring的BeanUtils来复制属性,我认为这些属性会给我一个非托管的副本,但它们并不都是持久的,所以一定不能。然后我通过我的entityManager添加了分离以尝试确保它已分离,但是在服务层中我仍然可以看到“getNode”方法出现了一堆结果,即使数据库被擦除干净。 / p>

有没有简单明智的方法来复制我的实体而没有Hibernate每次都会挫败我?

1 个答案:

答案 0 :(得分:1)

原来我的问题是他们的主键,他们的Id,设置为原始节点的主键。当我手动将副本的Id设置为0时,它工作正常。我正在使用MySQL,因此不确定这是否适用于其他数据库,但考虑到java“int”的默认值始终为0,它应该。