EntityManager.persist() 有效,但 EntityManager.merge() 无效
EntityManager.persist() works, but EntityManager.merge() does not
我们正在使用 EclipseLink 2.5.2 和 WildFly 9.0.0。
这是一个每小时调用一定次数的方法(由 EJB 计时器指定)。出于测试目的,我将其更改为每分钟触发一次,在我的特定配置中,由于要进行 10 次更新,因此每分钟将调用此方法 10 次:
@Stateless
public class NetCentricDataService {
@PersistenceContext(unitName = "NetCentricPersistenceUnit")
private EntityManager em;
public void insertUpdate(A a, B b, boolean insert) {
if (insert) {
em.persist(a);
em.flush();
if (b != null) {
em.persist(b);
em.flush();
}
} else {
em.merge(a);
if (b != null) {
em.merge(b);
}
em.flush();
}
}
}
当我清除与下面两个实体 classes 关联的表时,if(insert)
块执行,persist
调用工作正常,数据库更新;但是,如果 DB 中存在现有条目,则会执行 else
块,merge
调用 运行 而没有 Exception
,但不会更新 DB。方法调用完成后,我正在 SQL Developer 中进行检查。
编辑:例如,以下内容不起作用:
A a = dataService.getA(); // gets exisiting A from DB
a.setSubject("My Subject");
B b = dataService.getB(); // gets existing B from DB
b.setFoo(123.45);
insertUpdate(a, b, false);
这是实体 class A:
@Entity
@Table(name = "A")
@SuppressWarnings("unused")
public class A implements Serializable {
/**
* Method called by container before DB insert.
*/
@PrePersist
public void beforeInsert() {
if (objectType == null) {
objectType = ObjectTypeEnum.UNKNOWN;
}
}
@Id
@Column(name = "MY_UID")
private String myUid;
@Column(name = "MY_NUMBER")
private int myNumber;
@Column(name = "SUBJECT")
private String subject;
@Enumerated(EnumType.ORDINAL)
@Column(name = "OBJECT_TYPE")
private ObjectTypeEnum objectType;
// other columns, getters, setters, equals, etc.
}
这里是实体 class B:
@Entity
@Table(name = "B")
@SuppressWarnings("unused")
public class B implements Serializable {
@Id
@Column(name = "MY_UID", nullable = false)
private String myUid;
@Column(name = "FOO")
private double foo;
@Column(name = "BAR")
private double bar;
}
注:B中的MY_UID是A中MY_UID的外键。
注意:在我尝试更新的任何列上都没有 updatable=false 属性。
让我知道是否还有其他 files/methods/etc。我可以包括或者如果我可以提供更多信息。还值得注意的是,我不维护我发布的任何代码,但我最近一直在使用它。我问维护者,他说他不确定为什么会这样。在此先感谢您的帮助!
编辑 - 这是独立的数据源配置-full.xml:
<subsystem xmlns="urn:jboss:domain:datasources:3.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>****</password>
</security>
</datasource>
<datasource jta="true" jndi-name="java:jboss/datasources/SFDS" pool-name="SFDS" enabled="true" use-java-context="true" use-ccm="true">
<connection-url>jdbc:oracle:thin:@DB:1521:ORACLE_SID</connection-url>
<driver>ojdbc6</driver>
<new-connection-sql>select 1 from dual</new-connection-sql>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>100</max-pool-size>
<prefill>false</prefill>
<use-strict-min>false</use-strict-min>
<flush-strategy>FailingConnectionOnly</flush-strategy>
</pool>
<security>
<user-name>wildfly_user</user-name>
<password>****</password>
</security>
<validation>
<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
<use-fast-fail>true</use-fast-fail>
</validation>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="ojdbc6" module="com.oracle.jdbc">
<xa-datasource-class>oracle.jdbc.OracleDriver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
问题似乎是在尝试调用 merge
之前,我们调用了带有只读提示的 SELECT
查询。删除此提示允许合并成功显示在数据库中。感谢克里斯的帮助!
我们正在使用 EclipseLink 2.5.2 和 WildFly 9.0.0。
这是一个每小时调用一定次数的方法(由 EJB 计时器指定)。出于测试目的,我将其更改为每分钟触发一次,在我的特定配置中,由于要进行 10 次更新,因此每分钟将调用此方法 10 次:
@Stateless
public class NetCentricDataService {
@PersistenceContext(unitName = "NetCentricPersistenceUnit")
private EntityManager em;
public void insertUpdate(A a, B b, boolean insert) {
if (insert) {
em.persist(a);
em.flush();
if (b != null) {
em.persist(b);
em.flush();
}
} else {
em.merge(a);
if (b != null) {
em.merge(b);
}
em.flush();
}
}
}
当我清除与下面两个实体 classes 关联的表时,if(insert)
块执行,persist
调用工作正常,数据库更新;但是,如果 DB 中存在现有条目,则会执行 else
块,merge
调用 运行 而没有 Exception
,但不会更新 DB。方法调用完成后,我正在 SQL Developer 中进行检查。
编辑:例如,以下内容不起作用:
A a = dataService.getA(); // gets exisiting A from DB
a.setSubject("My Subject");
B b = dataService.getB(); // gets existing B from DB
b.setFoo(123.45);
insertUpdate(a, b, false);
这是实体 class A:
@Entity
@Table(name = "A")
@SuppressWarnings("unused")
public class A implements Serializable {
/**
* Method called by container before DB insert.
*/
@PrePersist
public void beforeInsert() {
if (objectType == null) {
objectType = ObjectTypeEnum.UNKNOWN;
}
}
@Id
@Column(name = "MY_UID")
private String myUid;
@Column(name = "MY_NUMBER")
private int myNumber;
@Column(name = "SUBJECT")
private String subject;
@Enumerated(EnumType.ORDINAL)
@Column(name = "OBJECT_TYPE")
private ObjectTypeEnum objectType;
// other columns, getters, setters, equals, etc.
}
这里是实体 class B:
@Entity
@Table(name = "B")
@SuppressWarnings("unused")
public class B implements Serializable {
@Id
@Column(name = "MY_UID", nullable = false)
private String myUid;
@Column(name = "FOO")
private double foo;
@Column(name = "BAR")
private double bar;
}
注:B中的MY_UID是A中MY_UID的外键。
注意:在我尝试更新的任何列上都没有 updatable=false 属性。
让我知道是否还有其他 files/methods/etc。我可以包括或者如果我可以提供更多信息。还值得注意的是,我不维护我发布的任何代码,但我最近一直在使用它。我问维护者,他说他不确定为什么会这样。在此先感谢您的帮助!
编辑 - 这是独立的数据源配置-full.xml:
<subsystem xmlns="urn:jboss:domain:datasources:3.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>****</password>
</security>
</datasource>
<datasource jta="true" jndi-name="java:jboss/datasources/SFDS" pool-name="SFDS" enabled="true" use-java-context="true" use-ccm="true">
<connection-url>jdbc:oracle:thin:@DB:1521:ORACLE_SID</connection-url>
<driver>ojdbc6</driver>
<new-connection-sql>select 1 from dual</new-connection-sql>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>100</max-pool-size>
<prefill>false</prefill>
<use-strict-min>false</use-strict-min>
<flush-strategy>FailingConnectionOnly</flush-strategy>
</pool>
<security>
<user-name>wildfly_user</user-name>
<password>****</password>
</security>
<validation>
<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
<use-fast-fail>true</use-fast-fail>
</validation>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="ojdbc6" module="com.oracle.jdbc">
<xa-datasource-class>oracle.jdbc.OracleDriver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
问题似乎是在尝试调用 merge
之前,我们调用了带有只读提示的 SELECT
查询。删除此提示允许合并成功显示在数据库中。感谢克里斯的帮助!