2013-02-09 41 views
2

我有一个使用Spring的Java应用程序,以及使用JPA 2.0规范的Hibernate。Hibernate's shenanigans - 我只想要一个非托管副本

我试图在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阻止我动不动?

+0

该实体确实有一个与坐标分开的ID,这显然是被分配的,所以这可能是问题的一部分?但是,如果id是自动生成的int,那么在复制时如何将它清空?如果这是问题? – CorayThan 2013-02-09 09:43:17

回答

1

原来我的问题是,他们的主键,他们的ID,设置为原始节点的主键。当我手动设置副本的ID为0时,它工作。我正在使用MySQL,所以不知道这是否可以与其他数据库一起工作,但考虑一个java“int”的默认值总是为0,它应该。

+1

你是对的,当将一个实体重新连接到会话时,Hibernate会通过它的主键来确定它是新记录还是旧记录的更新。在非JPA Hibernate中,什么值取决于很少需要的['unsaved-value'映射属性](http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping的.html#映射声明-ID)。默认声称是“合理的”,所以我猜它是任何类型对未初始化变量的值。 ('0','null'等) – millimoose 2013-02-09 22:41:23