分离实体上的JPA merge()在存在时进行插入

时间:2014-11-14 14:26:10

标签: java hibernate jpa

我将JPA与hibernate提供程序一起使用。继承我的部分代码:

@Entity
@IdClass(xxxPK.class)
@NamedQueries({
...
})
@Inheritance(strategy = InheritanceType.JOINED)
public class xxx extends AbstractEntity {

public static final String GET_TRADES = "getInstruments";
public static final String GET_STRUCTURE = "getStructure";
public static final String GET_ALL = "getAllTrades";

@Column(nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "xxx")
@SequenceGenerator(name = "xxxx", sequenceName = "xxxxS", allocationSize = 1)
private Long systemId;

@Id
@Column(nullable = false)
private Integer version;
 //////

后代:

@Entity
@PrimaryKeyJoinColumns(
    {
            @PrimaryKeyJoinColumn(name = "systemId"),
            @PrimaryKeyJoinColumn(name = "version")
    }
)
public class YYY extends xxx {
 //////

我创建了一个YYY实例,persiti就像我期望的那样。之后我在db中的每个表中都有一行:

fx = Persistence.invoke(new Persistence.Invoke<YYY>() {
            @Override
            public YYY run(EntityManager em) {
                BufferedReader reader = null;
                try {
                    reader = new BufferedReader(new FileReader(new ClassPathResource("json/XXX_from.json").getFile()));
                } catch (IOException ex) {
                    System.out.print("File is not found");
                }
                YYYfx = (YYY) EntityConverter.getConverter(YYY.class).fromJson(reader);
                em.persist(fx);
                return fx;
            }
        });

所以,之后fx被分离并且作为SPEC。我可以通过调用merge()使它在另一个会话中持久化,所以调用它但是:

Persistence.invoke(new Persistence.Invoke<Object>() {
    @Override
    public Object run(EntityManager em) {
        fx.setZZZ("A");
        em.merge(fx);
        return null;
    }
});

之后我在XXX和YYY表格中有另一行有一个新的主要。它看起来像提供者将fx作为TRANSIENT而不是DETACHED然后它是好的 - 它是一个新对象,我会插入它。 我不知道该做什么我在这种愚蠢的情况下失去了4个小时。请帮忙!

public class Persistence {

    private static EntityManagerFactory emf;

    public static EntityManagerFactory getEmf() {
        return emf;
    }

    public void setEmf(EntityManagerFactory emf) {
        Persistence.emf = emf;
    }

    public static <T> T invoke(Invoke<T> inv) {
        T result = null;
        EntityManager em = getEmf().createEntityManager();
        EntityTransaction transaction = em.getTransaction();
        transaction.begin();
            try {
            result = inv.run(em);
            transaction.commit();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            em.close();
        }
        return result;
    }

    public interface Invoke<T> {
        public T run(EntityManager em);
    }

}

1 个答案:

答案 0 :(得分:1)

请参阅API:

https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge(T)

  

返回:状态合并到

的托管实例

从第一次电话开始:

return em.persist(fx);

http://www.objectdb.com/java/jpa/persistence/detach

  

可以使用以下方法将分离的对象附加到任何EntityManager   合并方法:

     

指定的分离实体对象的内容被复制到具有相同标识的现有管理实体对象中(即   相同类型和主键)。如果EntityManager不管理此类   实体对象,然后构造新的管理实体对象。的的   但是,分离的对象本身保持不变和分离