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

Java 分离实体上的JPA merge()在其存在时进行插入,java,hibernate,jpa,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 f

我将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实例,persti与我预期的一样。之后,我在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=Persistence.invoke(新的Persistence.invoke(){
@凌驾
公共YYY运行(EntityManager em){
BufferedReader reader=null;
试一试{
reader=new BufferedReader(new FileReader(new ClassPathResource(“json/XXX_from.json”).getFile());
}捕获(IOEX异常){
System.out.print(“未找到文件”);
}
yyyyfx=(YYY)EntityConverter.getConverter(YYY.class).fromJson(阅读器);
em.persist(fx);
外汇收益;
}
});
因此,在分离fx之后,按照SPEC.sais,我可以通过调用merge()使其在另一个会话中保持不变,所以调用它,但是:

Persistence.invoke(new Persistence.Invoke<Object>() {
    @Override
    public Object run(EntityManager em) {
        fx.setZZZ("A");
        em.merge(fx);
        return null;
    }
});
Persistence.invoke(新的Persistence.invoke(){
@凌驾
公共对象运行(EntityManager em){
外汇基金。setZZZ(“A”);
em.merge(fx);
返回null;
}
});
之后,我在XXX和YYY表中有另一行,其中有一个新的主行。看起来提供者将fx视为暂时的,而不是分离的,然后它说没问题-这是一个新对象,我会插入它。 我不知道该怎么办我在这样愚蠢的案子上浪费了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);
    }

}
公共类持久化{
私有静态实体管理器工厂emf;
公共静态EntityManagerFactory getEmf(){
返回电动势;
}
public void setEmf(EntityManagerFactory emf){
Persistence.emf=emf;
}
公共静态T调用(invoke inv){
T结果=null;
EntityManager em=getEmf().createEntityManager();
EntityTransaction=em.getTransaction();
transaction.begin();
试一试{
结果=库存运行(em);
commit();
}捕获(例外e){
抛出新的运行时异常(e);
}最后{
em.close();
}
返回结果;
}
公共接口调用{
公共T运行(实体管理器em);
}
}
参见API:

返回:状态合并到的托管实例

因此,从您的第一个电话:

return em.persist(fx);

通过使用,可以将分离的对象附着到任何EntityManager 合并方法:

将指定分离实体对象的内容复制到具有相同标识(即。 相同类型和主键)。如果EntityManager没有管理这些 实体对象,但新的托管实体对象被构造最新版本 但是,分离的对象本身保持不变并已分离