標準的Java EE環境:JPA + EJB從JSF豆調用。服務器:GlassFish的3.1.1JPA。交易問題,而從休眠遷移到EclipseLink的
守則,開發,測試和部署Hibernate作爲JPA提供者,拒絕與EclipseLink的堅持實體 - 在GlassFish中的默認JPA提供商:
下面是我從JSF豆調用代碼:
@Singleton
@Startup
public class SecurityService {
@PersistenceContext(unitName = "unit01")
private EntityManager em;
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
public String createNewUser(String login) {
UserImpl newUser = new UserImpl();
newUser.setLogin(login);
em.persist(newUser);
//em.flush() ------> works fine when uncommented
DirectoryImpl userHome = new DirectoryImpl();
userHome.setOwner(newUser);
em.persist(userHome); // Throws exception due to FK violation
//
//
至於評論,如果我堅持新用戶,這顯然是錯誤後沖洗EntityManager的代碼才起作用。在測試其他方法時,我發現只有在關閉服務器時纔會將其他更改刷新到數據庫。
以上所有發生在一個新的GF安裝,純Java EE的設計沒有任何Spring或任何框架。
這裏是我的persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="unit01" transaction-type="JTA">
<jta-data-source>jdbc/Unit01DS</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
這是我如何創建數據源:
asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource --restype javax.sql.ConnectionPoolDataSource --property "User=u1:Password=xxx:URL=jdbc\:mysql\://localhost/dbname" Unit01DS
asadmin create-jdbc-resource --connectionpoolid Unit01DS jdbc/Unit01DS
這一切,沒有其他的配置文件/使用的選項。那麼爲什麼我的代碼在Hibernate下工作良好,並且在Eclipselink下表現完全不同?有任何想法嗎?
UPDATE
進一步的調查表明,問題就出在實體映射的地方。在我的情況都提到實體(UserImpl
和DirectoryImpl
)從一個根類繼承,如下所示:
@Entity
@Table(name = "ob10object")
@Inheritance(strategy = InheritanceType.JOINED)
public class RootObjectImpl implements RootObject {
private Long id;
@Id
@Column(name = "ob10id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
//
UserImpl
是根實體的直接子類,並有向其他實體
@Entity
@Table(name = "as10user")
@DiscriminatorValue(value = "AS10")
public class UserImpl extends RootObjectImpl implements User {
private String login;
//
//
沒有引用
有點複雜的情況是DirectoryImpl
:
@Entity
@Table(name = "st20directory")
@DiscriminatorValue(value = "ST20")
public class DirectoryImpl extends AbstractStorageNode implements Directory {
// Inside there are also no references to other entities
WHE再AbstractStorageNode
還延伸根對象:
@Entity
@Table(name = "st10storage_node")
public abstract class AbstractStorageNode extends RootObjectImpl implements StorageNode {
private Set<AbstractStorageNode> childNodes;
private StorageNode parentNode;
private User owner;
@OneToMany(mappedBy = "parentNode")
public Set<AbstractStorageNode> getChildNodes() {
return childNodes;
}
@ManyToOne(targetEntity = AbstractStorageNode.class)
@JoinColumn(name="st10parent", nullable = true)
public StorageNode getParentNode() {
return parentNode;
}
@ManyToOne(targetEntity = UserImpl.class)
@JoinColumn(name = "as10id") // this is FK to `UserImpl` table.
public User getOwner() {
return owner;
}
// Setters omitted
現在這裏是生成的sql:
// Creating user:
INSERT INTO ob10object (field1, field2, ob10discriminator) VALUES ('v1', 'v2', 'AS10')
SELECT LAST_INSERT_ID()
// Creating Directory:
INSERT INTO ob10object (field1, field2, ob10discriminator) VALUES ('v11', 'v22', 'ST20')
SELECT LAST_INSERT_ID()
INSERT INTO st10storage_node (st10name, as10id, st10parent, ob10id) VALUES ('home', 10, null, 11)
現在我看看會發生什麼:的EclipseLink不將數據插入到用戶表(as10user),造成FK違反最後一個查詢。但我仍然不知道爲什麼會這樣。
更新2
這裏是個例外:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`dbname`.`st10storage_node`, CONSTRAINT `F_ST10_AS10` FOREIGN KEY (`as10id`) REFERENCES `as10user` (`ob10id`))
Error Code: 1452
我也有同樣的問題。看起來Hibernate JPA持久性提供程序緩存體系結構與EclipseLink不同,但我找不到解決方法。這裏有一篇有趣的文章,可能有助於... http://blogs.oracle.com/carolmcdonald/entry/jpa_caching – perissf
@perissf,謝謝你的文章。總是認爲緩存是規範背後的事情,如果供應商不違反規範,供應商可以自由使用任何緩存機制。我稍微被我在這裏得到的東西嗤之以鼻,我堅信我錯過了一些配置選項。 – Osw