2

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

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

不过,我一直遇到问题,并不是所有我想要坚持的问题都被坚持下去,而且它的休眠/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”方法出现了一堆结果,即使数据库被清除干净。

是否有任何简单而理智的方法来复制我的实体而不会让 Hibernate 每次都阻止我?

4

1 回答 1

1

Turns out my issue was that they had their primarykey, their Id, set to the primary key of the original node. When I manually set the Id of the copies to 0, it worked. I'm using MySQL, so not sure if that would work with other databases, but considering a java "int" always has a default value of 0, it should.

于 2013-02-09T22:22:51.863 回答