You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by jr...@apache.org on 2009/07/24 18:27:31 UTC
svn commit: r797551 - in /openjpa/trunk:
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/
openjpa-persistence/src/main/java/org/apache/openjpa/persistence/
Author: jrbauer
Date: Fri Jul 24 16:27:30 2009
New Revision: 797551
URL: http://svn.apache.org/viewvc?rev=797551&view=rev
Log:
OPENJPA-1175 Initial implementation and tests for ProviderUtil and PerisistenceUnitUtil
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java (with props)
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import java.sql.Date;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Embeddable
+public class EagerEmbed {
+
+ @Temporal(TemporalType.DATE)
+ private Date startDate;
+
+ @Temporal(TemporalType.DATE)
+ private Date endDate;
+
+ public void setStartDate(Date startDate) {
+ this.startDate = startDate;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public void setEndDate(Date endDate) {
+ this.endDate = endDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEmbed.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import javax.persistence.Basic;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+@Entity
+public class EagerEntity {
+
+ @Id
+ private int id;
+
+ @Basic
+ private String name;
+
+ @Embedded
+ private EagerEmbed eagerEmbed;
+
+ @Transient
+ private String transField;
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setEagerEmbed(EagerEmbed eagerEmbed) {
+ this.eagerEmbed = eagerEmbed;
+ }
+
+ public EagerEmbed getEagerEmbed() {
+ return eagerEmbed;
+ }
+
+ public void setTransField(String transField) {
+ this.transField = transField;
+ }
+
+ public String getTransField() {
+ return transField;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/EagerEntity.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import java.sql.Date;
+
+import javax.persistence.Basic;
+import javax.persistence.Embeddable;
+import javax.persistence.FetchType;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Embeddable
+public class LazyEmbed {
+
+ @Temporal(TemporalType.DATE)
+ @Basic(fetch=FetchType.LAZY)
+ private Date startDate;
+
+ @Temporal(TemporalType.DATE)
+ @Basic(fetch=FetchType.LAZY)
+ private Date endDate;
+
+ public void setStartDate(Date startDate) {
+ this.startDate = startDate;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public void setEndDate(Date endDate) {
+ this.endDate = endDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEmbed.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import javax.persistence.Basic;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+@Entity
+public class LazyEntity {
+
+ @Id
+ private int id;
+
+ @Basic(fetch=FetchType.LAZY)
+ private String name;
+
+ @Embedded
+ private LazyEmbed lazyEmbed;
+
+ @Transient
+ private String transField;
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setLazyEmbed(LazyEmbed lazyEmbed) {
+ this.lazyEmbed = lazyEmbed;
+ }
+
+ public LazyEmbed getLazyEmbed() {
+ return lazyEmbed;
+ }
+
+ public void setTransField(String transField) {
+ this.transField = transField;
+ }
+
+ public String getTransField() {
+ return transField;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/LazyEntity.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import java.sql.Date;
+import java.util.Random;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.spi.LoadState;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.ProviderUtil;
+
+import org.apache.openjpa.persistence.PersistenceProviderImpl;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestPersistenceUnitUtil extends SingleEMFTestCase{
+
+ public void setUp() {
+ setUp(CLEAR_TABLES, EagerEntity.class, LazyEmbed.class,
+ LazyEntity.class, EagerEmbed.class);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * load state.
+ */
+ public void testIsLoadedEager() {
+ verifyIsLoadedEagerState(true);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * not loaded state.
+ */
+ public void testNotLoadedLazy() {
+ verifyIsLoadedEagerState(false);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * loaded state.
+ */
+ public void testIsLoadedLazy() {
+ verifyIsLoadedLazyState(true);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * NOT_LOADED state.
+ */
+ public void testNotLoadedEager() {
+ verifyIsLoadedEagerState(false);
+ }
+
+
+ private void verifyIsLoadedEagerState(boolean loaded) {
+ PersistenceUnitUtil puu = emf.getPersistenceUnitUtil();
+ assertSame(emf, puu);
+ EntityManager em = emf.createEntityManager();
+ EagerEntity ee = createEagerEntity();
+
+ // Vfy LoadState is false for the unmanaged entity
+ assertEquals(false, puu.isLoaded(ee));
+ assertEquals(false, puu.isLoaded(ee,
+ "id"));
+
+ em.getTransaction().begin();
+ em.persist(ee);
+ em.getTransaction().commit();
+ em.clear();
+
+ if (loaded)
+ ee = em.find(EagerEntity.class, ee.getId());
+ else
+ ee = em.getReference(EagerEntity.class, ee.getId());
+
+ assertEquals(loaded, puu.isLoaded(ee));
+ assertEquals(loaded, puu.isLoaded(ee, "id"));
+ assertEquals(loaded, puu.isLoaded(ee, "name"));
+ assertEquals(loaded, puu.isLoaded(ee, "eagerEmbed"));
+ assertEquals(false, puu.isLoaded(ee, "transField"));
+
+ em.close();
+ }
+
+ private void verifyIsLoadedLazyState(boolean loaded) {
+ PersistenceUnitUtil puu = emf.getPersistenceUnitUtil();
+ assertSame(emf, puu);
+ EntityManager em = emf.createEntityManager();
+ LazyEntity le = createLazyEntity();
+
+ // Vfy LoadState is false for the unmanaged entity
+ assertEquals(false, puu.isLoaded(le));
+ assertEquals(false, puu.isLoaded(le,"id"));
+
+ em.getTransaction().begin();
+ em.persist(le);
+ em.getTransaction().commit();
+ em.clear();
+
+ // Use find or getReference based upon expected state
+ if (loaded)
+ le = em.find(LazyEntity.class, le.getId());
+ else
+ le = em.getReference(LazyEntity.class, le.getId());
+
+ assertEquals(loaded, puu.isLoaded(le));
+ assertEquals(loaded, puu.isLoaded(le, "id"));
+
+ // Name is lazy fetch so it should not be loaded
+ assertEquals(false, puu.isLoaded(le, "name"));
+ assertEquals(loaded, puu.isLoaded(le, "lazyEmbed"));
+ assertEquals(false, puu.isLoaded(le, "transField"));
+
+ em.close();
+ }
+
+ /*
+ * Verifies that an entity and attributes are considered loaded if they
+ * are assigned by the application.
+ */
+ public void testIsApplicationLoaded() {
+ PersistenceUnitUtil puu = emf.getPersistenceUnitUtil();
+ assertSame(emf, puu);
+ EntityManager em = emf.createEntityManager();
+ EagerEntity ee = createEagerEntity();
+
+ em.getTransaction().begin();
+ em.persist(ee);
+ em.getTransaction().commit();
+ em.clear();
+
+ ee = em.getReference(EagerEntity.class, ee.getId());
+ assertNotNull(ee);
+ assertEagerLoadState(puu, ee, false);
+
+ ee.setName("AppEagerName");
+ EagerEmbed emb = createEagerEmbed();
+ ee.setEagerEmbed(emb);
+ // Assert fields are loaded via application loading
+ assertEagerLoadState(puu, ee, true);
+ // Vfy the set values are applied to the entity
+ assertEquals("AppEagerName", ee.getName());
+ assertEquals(emb, ee.getEagerEmbed());
+
+ em.close();
+ }
+
+ private EagerEntity createEagerEntity() {
+ EagerEntity ee = new EagerEntity();
+ ee.setId(new Random().nextInt());
+ ee.setName("EagerEntity");
+ EagerEmbed emb = createEagerEmbed();
+ ee.setEagerEmbed(emb);
+ return ee;
+ }
+
+ private EagerEmbed createEagerEmbed() {
+ EagerEmbed emb = new EagerEmbed();
+ emb.setEndDate(new Date(System.currentTimeMillis()));
+ emb.setStartDate(new Date(System.currentTimeMillis()));
+ return emb;
+ }
+
+ private LazyEntity createLazyEntity() {
+ LazyEntity le = new LazyEntity();
+ le.setId(new Random().nextInt());
+ le.setName("LazyEntity");
+ LazyEmbed emb = new LazyEmbed();
+ emb.setEndDate(new Date(System.currentTimeMillis()));
+ emb.setStartDate(new Date(System.currentTimeMillis()));
+ le.setLazyEmbed(emb);
+ return le;
+ }
+
+ private void assertEagerLoadState(PersistenceUnitUtil pu, Object ent,
+ boolean state) {
+ assertEquals(state, pu.isLoaded(ent));
+ assertEquals(state, pu.isLoaded(ent, "id"));
+ assertEquals(state, pu.isLoaded(ent, "name"));
+ assertEquals(state, pu.isLoaded(ent, "eagerEmbed"));
+ assertEquals(false, pu.isLoaded(ent, "transField"));
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestPersistenceUnitUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java?rev=797551&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java Fri Jul 24 16:27:30 2009
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.util;
+
+import java.sql.Date;
+import java.util.Random;
+
+import javax.persistence.EntityManager;
+import javax.persistence.spi.LoadState;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.ProviderUtil;
+
+import org.apache.openjpa.persistence.PersistenceProviderImpl;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestProviderUtil extends SingleEMFTestCase{
+
+ public void setUp() {
+ setUp(CLEAR_TABLES, EagerEntity.class, LazyEmbed.class,
+ LazyEntity.class, EagerEmbed.class);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * LOADED state.
+ */
+ public void testIsLoadedEager() {
+ verifyIsLoadedEagerState(LoadState.LOADED);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * NOT_LOADED state.
+ */
+ public void testNotLoadedLazy() {
+ verifyIsLoadedEagerState(LoadState.NOT_LOADED);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * LOADED state.
+ */
+ public void testIsLoadedLazy() {
+ verifyIsLoadedLazyState(LoadState.LOADED);
+ }
+
+ /*
+ * Verifies an entity and its persistent attributes are in the proper
+ * NOT_LOADED state.
+ */
+ public void testNotLoadedEager() {
+ verifyIsLoadedEagerState(LoadState.NOT_LOADED);
+ }
+
+
+ private void verifyIsLoadedEagerState(LoadState state) {
+ ProviderUtil pu = getProviderUtil();
+ EntityManager em = emf.createEntityManager();
+ EagerEntity ee = createEagerEntity();
+
+ // Vfy LoadState is unknown for the unmanaged entity
+ assertEquals(LoadState.UNKNOWN, pu.isLoaded(ee));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(ee,
+ "id"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(ee,
+ "id"));
+
+ em.getTransaction().begin();
+ em.persist(ee);
+ em.getTransaction().commit();
+ em.clear();
+
+ if (state == LoadState.LOADED)
+ ee = em.find(EagerEntity.class, ee.getId());
+ else
+ ee = em.getReference(EagerEntity.class, ee.getId());
+
+ assertEquals(state, pu.isLoaded(ee));
+ assertEquals(state, pu.isLoadedWithReference(ee,
+ "id"));
+ assertEquals(state, pu.isLoadedWithoutReference(ee,
+ "id"));
+ assertEquals(state, pu.isLoadedWithReference(ee,
+ "name"));
+ assertEquals(state, pu.isLoadedWithoutReference(ee,
+ "name"));
+ assertEquals(state, pu.isLoadedWithReference(ee,
+ "eagerEmbed"));
+ assertEquals(state, pu.isLoadedWithoutReference(ee,
+ "eagerEmbed"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(ee,
+ "transField"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(ee,
+ "transField"));
+
+ em.close();
+ }
+
+ private void verifyIsLoadedLazyState(LoadState state) {
+ ProviderUtil pu = getProviderUtil();
+ EntityManager em = emf.createEntityManager();
+ LazyEntity le = createLazyEntity();
+
+ // Vfy LoadState is unknown for the unmanaged entity
+ assertEquals(LoadState.UNKNOWN, pu.isLoaded(le));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(le,
+ "id"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(le,
+ "id"));
+
+ em.getTransaction().begin();
+ em.persist(le);
+ em.getTransaction().commit();
+ em.clear();
+
+ // Use find or getReference based upon expected state
+ if (state == LoadState.LOADED)
+ le = em.find(LazyEntity.class, le.getId());
+ else
+ le = em.getReference(LazyEntity.class, le.getId());
+
+ assertEquals(state, pu.isLoaded(le));
+ assertEquals(state, pu.isLoadedWithReference(le,
+ "id"));
+ assertEquals(state, pu.isLoadedWithoutReference(le,
+ "id"));
+ // Name is lazy fetch so it should not be loaded
+ assertEquals(LoadState.NOT_LOADED, pu.isLoadedWithReference(le,
+ "name"));
+ assertEquals(LoadState.NOT_LOADED, pu.isLoadedWithoutReference(le,
+ "name"));
+ assertEquals(state, pu.isLoadedWithReference(le,
+ "lazyEmbed"));
+ assertEquals(state, pu.isLoadedWithoutReference(le,
+ "lazyEmbed"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(le,
+ "transField"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(le,
+ "transField"));
+
+ em.close();
+ }
+
+ /*
+ * Verifies that an entity and attributes are considered loaded if they
+ * are assigned by the application.
+ */
+ public void testIsApplicationLoaded() {
+ ProviderUtil pu = getProviderUtil();
+ EntityManager em = emf.createEntityManager();
+ EagerEntity ee = createEagerEntity();
+
+ em.getTransaction().begin();
+ em.persist(ee);
+ em.getTransaction().commit();
+ em.clear();
+
+ ee = em.getReference(EagerEntity.class, ee.getId());
+ assertNotNull(ee);
+ assertEagerLoadState(pu, ee, LoadState.NOT_LOADED);
+
+ ee.setName("AppEagerName");
+ EagerEmbed emb = createEagerEmbed();
+ ee.setEagerEmbed(emb);
+ // Assert fields are loaded via application loading
+ assertEagerLoadState(pu, ee, LoadState.LOADED);
+ // Vfy the set values are applied to the entity
+ assertEquals("AppEagerName", ee.getName());
+ assertEquals(emb, ee.getEagerEmbed());
+
+ em.close();
+ }
+
+ /*
+ * Verifies that an entity not managed by a PU
+ */
+ public void testIsLoadedUnknown() {
+ ProviderUtil pu = getProviderUtil();
+
+ EagerEntity ee = new EagerEntity();
+
+ assertEquals(LoadState.UNKNOWN, pu.isLoaded(ee));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(ee,
+ "id"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(ee,
+ "id"));
+ }
+
+ private EagerEntity createEagerEntity() {
+ EagerEntity ee = new EagerEntity();
+ ee.setId(new Random().nextInt());
+ ee.setName("EagerEntity");
+ EagerEmbed emb = createEagerEmbed();
+ ee.setEagerEmbed(emb);
+ return ee;
+ }
+
+ private EagerEmbed createEagerEmbed() {
+ EagerEmbed emb = new EagerEmbed();
+ emb.setEndDate(new Date(System.currentTimeMillis()));
+ emb.setStartDate(new Date(System.currentTimeMillis()));
+ return emb;
+ }
+
+ private LazyEntity createLazyEntity() {
+ LazyEntity le = new LazyEntity();
+ le.setId(new Random().nextInt());
+ le.setName("LazyEntity");
+ LazyEmbed emb = new LazyEmbed();
+ emb.setEndDate(new Date(System.currentTimeMillis()));
+ emb.setStartDate(new Date(System.currentTimeMillis()));
+ le.setLazyEmbed(emb);
+ return le;
+ }
+
+ private void assertEagerLoadState(ProviderUtil pu, Object ent,
+ LoadState state) {
+ assertEquals(state, pu.isLoaded(ent));
+ assertEquals(state, pu.isLoadedWithReference(ent,
+ "id"));
+ assertEquals(state, pu.isLoadedWithoutReference(ent,
+ "id"));
+ assertEquals(state, pu.isLoadedWithReference(ent,
+ "name"));
+ assertEquals(state, pu.isLoadedWithoutReference(ent,
+ "name"));
+ assertEquals(state, pu.isLoadedWithReference(ent,
+ "eagerEmbed"));
+ assertEquals(state, pu.isLoadedWithoutReference(ent,
+ "eagerEmbed"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithReference(ent,
+ "transField"));
+ assertEquals(LoadState.UNKNOWN, pu.isLoadedWithoutReference(ent,
+ "transField"));
+ }
+
+ private ProviderUtil getProviderUtil() {
+ PersistenceProvider pp = new PersistenceProviderImpl();
+ ProviderUtil pu = pp.getProviderUtil();
+ return pu;
+ }
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestProviderUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java?rev=797551&r1=797550&r2=797551&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java Fri Jul 24 16:27:30 2009
@@ -21,6 +21,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.BitSet;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
@@ -32,22 +34,25 @@
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.criteria.QueryBuilder;
-import javax.persistence.metamodel.Metamodel;
import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.Reflection;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
import org.apache.openjpa.kernel.AutoDetach;
import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.kernel.DelegatingBrokerFactory;
import org.apache.openjpa.kernel.DelegatingFetchConfiguration;
import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.conf.Value;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.persistence.criteria.CriteriaBuilder;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.query.OpenJPAQueryBuilder;
@@ -64,7 +69,7 @@
*/
public class EntityManagerFactoryImpl
implements OpenJPAEntityManagerFactory, OpenJPAEntityManagerFactorySPI,
- Closeable {
+ Closeable, PersistenceUnitUtil {
private static final Localizer _loc = Localizer.forPackage
(EntityManagerFactoryImpl.class);
@@ -379,7 +384,107 @@
}
public PersistenceUnitUtil getPersistenceUnitUtil() {
- // TODO Auto-generated method stub
+ return this;
+ }
+
+ /**
+ * Get the identifier for the specified entity. If not managed by any
+ * of the em's in this PU or not persistence capable, return null.
+ */
+ public Object getIdentifier(Object entity) {
+ if (entity instanceof PersistenceCapable) {
+ PersistenceCapable pc = (PersistenceCapable)entity;
+ // Per contract, if not managed by the owning emf, return null.
+ if (!isManagedBy(pc))
+ return null;
+ StateManager sm = pc.pcGetStateManager();
+
+ if (sm != null && sm instanceof OpenJPAStateManager) {
+ OpenJPAStateManager osm = (OpenJPAStateManager)sm;
+ return osm.getObjectId();
+ }
+ }
return null;
}
+
+ public boolean isLoaded(Object entity) {
+ return isLoaded(entity, null);
+ }
+
+ public boolean isLoaded(Object entity, String attribute) {
+ if (entity == null)
+ return false;
+
+ if (entity instanceof PersistenceCapable) {
+ PersistenceCapable pc = (PersistenceCapable)entity;
+ if (!isManagedBy(pc))
+ return false;
+ StateManager sm = pc.pcGetStateManager();
+ if (sm != null && sm instanceof OpenJPAStateManager)
+ return isLoaded((OpenJPAStateManager)sm, attribute);
+ }
+ return false;
+ }
+
+ /**
+ * Determines whether the specified state manager is managed by a broker
+ * within the persistence unit of this util instance.
+ * @param sm StateManager
+ * @return true if this state manager is managed by a broker within
+ * this persistence unit.
+ */
+ private boolean isManagedBy(PersistenceCapable entity) {
+ if (!isOpen())
+ return false;
+ Object abfobj = JPAFacadeHelper.toBrokerFactory(this);
+ if (abfobj == null)
+ return false;
+ if (abfobj instanceof AbstractBrokerFactory) {
+ AbstractBrokerFactory abf = (AbstractBrokerFactory)abfobj;
+ Collection<?> brokers = abf.getOpenBrokers();
+ if (brokers == null || brokers.size() == 0)
+ return false;
+ // Cycle through all brokers managed by this factory.
+ Broker[] brokerArr = brokers.toArray(new Broker[brokers.size()]);
+ for (Broker broker : brokerArr) {
+ if (broker != null && !broker.isClosed() &&
+ broker.isPersistent(entity))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the load state for a given state manager and attribute. If
+ * attr is null, only determines the load state based upon all persistent
+ * attributes. If an attribute is specified and not known to be
+ * persistent by this provider, returns false.
+ */
+ private boolean isLoaded(OpenJPAStateManager sm, String attr) {
+ boolean isLoaded = true;
+ BitSet loadSet = sm.getLoaded();
+ if (attr != null) {
+ FieldMetaData fmd = sm.getMetaData().getField(attr);
+ // Could not find field metadata for the specified attribute.
+ if (fmd == null)
+ return false;
+ // If the attribute is not loaded, return false.
+ if (!loadSet.get(fmd.getIndex()))
+ return false;
+ }
+ // Check load state of all persistent eager fetch attributes. Per
+ // contract, if any of them are not loaded, return false.
+ FieldMetaData[] fmds = sm.getMetaData().getFields();
+ for (FieldMetaData fmd : fmds) {
+ if (fmd.isInDefaultFetchGroup()) {
+ if (!loadSet.get(fmd.getIndex())) {
+ isLoaded = false;
+ break;
+ }
+ // TODO JRB: Complete contract for collections
+ }
+ }
+ return isLoaded;
+ }
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java?rev=797551&r1=797550&r2=797551&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java Fri Jul 24 16:27:30 2009
@@ -21,6 +21,7 @@
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
+import java.util.BitSet;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.spi.ClassTransformer;
@@ -34,18 +35,22 @@
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.enhance.PCClassFileTransformer;
import org.apache.openjpa.enhance.PCEnhancerAgent;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
import org.apache.openjpa.kernel.Bootstrap;
import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.ConfigurationProvider;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
+import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.validation.ValidationUtils;
import org.apache.openjpa.util.ClassResolver;
-import org.apache.openjpa.validation.ValidationException;
/**
@@ -56,7 +61,7 @@
* @published
*/
public class PersistenceProviderImpl
- implements PersistenceProvider {
+ implements PersistenceProvider, ProviderUtil {
static final String CLASS_TRANSFORMER_OPTIONS = "ClassTransformerOptions";
private static final String EMF_POOL = "EntityManagerFactoryPool";
@@ -182,6 +187,14 @@
}
/*
+ * Returns a ProviderUtil for use with entities managed by this
+ * persistence provider.
+ */
+ public ProviderUtil getProviderUtil() {
+ return this;
+ }
+
+ /*
* Returns a default Broker alias to be used when no openjpa.BrokerImpl
* is specified. This method allows PersistenceProvider subclass to
* override the default broker alias.
@@ -232,21 +245,6 @@
return _trans.transform(cl, name, previousVersion, pd, bytes);
}
}
-
- public LoadState isLoaded(Object arg0) {
- throw new UnsupportedOperationException(
- "JPA 2.0 - Method not yet implemented");
- }
-
- public LoadState isLoadedWithReference(Object arg0, String arg1) {
- throw new UnsupportedOperationException(
- "JPA 2.0 - Method not yet implemented");
- }
-
- public LoadState isLoadedWithoutReference(Object arg0, String arg1) {
- throw new UnsupportedOperationException(
- "JPA 2.0 - Method not yet implemented");
- }
/**
* This private worker method will attempt load the PCEnhancerAgent.
@@ -275,8 +273,99 @@
}
}
- public ProviderUtil getProviderUtil() {
- // TODO Auto-generated method stub
- return null;
+ /**
+ * Determines whether the specified object is loaded.
+ *
+ * @return LoadState.LOADED - if all implicit or explicit EAGER fetch
+ * attributes are loaded
+ * LoadState.NOT_LOADED - if any implicit or explicit EAGER fetch
+ * attribute is not loaded
+ * LoadState.UNKNOWN - if the entity is not managed by this
+ * provider.
+ */
+ public LoadState isLoaded(Object obj) {
+ return isLoadedWithoutReference(obj, null);
+ }
+
+ /**
+ * Determines whether the attribute on the specified object is loaded. This
+ * method may access the value of the attribute to determine load state (but
+ * currently does not).
+ *
+ * @return LoadState.LOADED - if the attribute is loaded.
+ * LoadState.NOT_LOADED - if the attribute is not loaded or any
+ * EAGER fetch attributes of the entity are not loaded.
+ * LoadState.UNKNOWN - if the entity is not managed by this
+ * provider or if it does not contain the persistent
+ * attribute.
+ */
+ public LoadState isLoadedWithReference(Object obj, String attr) {
+ // TODO: Are there be any cases where OpenJPA will need to examine
+ // the contents of a field to determine load state? If so, per JPA
+ // contract, this method permits that sort of access. In the extremely
+ // unlikely case that the the entity is managed by multiple providers,
+ // even if it doesn't trigger loading in OpenJPA, accessing field data
+ // could trigger loading by an alternate provider.
+ return isLoadedWithoutReference(obj, attr);
+ }
+
+ /**
+ * Determines whether the attribute on the specified object is loaded. This
+ * method does not access the value of the attribute to determine load
+ * state.
+ *
+ * @return LoadState.LOADED - if the attribute is loaded.
+ * LoadState.NOT_LOADED - if the attribute is not loaded or any
+ * EAGER fetch attributes of the entity are not loaded.
+ * LoadState.UNKNOWN - if the entity is not managed by this
+ * provider or if it does not contain the persistent
+ * attribute.
+ */
+ public LoadState isLoadedWithoutReference(Object obj, String attr) {
+
+ if (obj == null)
+ return LoadState.UNKNOWN;
+
+ // If the object has a state manager, call it directly.
+ if (obj instanceof PersistenceCapable) {
+ PersistenceCapable pc = (PersistenceCapable)obj;
+ StateManager sm = pc.pcGetStateManager();
+ if (sm != null && sm instanceof OpenJPAStateManager)
+ return isLoaded((OpenJPAStateManager)sm, attr);
+ }
+ return LoadState.UNKNOWN;
+ }
+
+ /*
+ * Returns the load state for a given state manager and attribute. If
+ * attr is null, determines the load state based upon all persistent
+ * attributes of the state manager. If an attribute is specified and not
+ * known to be persistent by this provider, returns a load state of unknown,
+ * otherwise, returns the load state of the attribute.
+ */
+ private LoadState isLoaded(OpenJPAStateManager sm, String attr) {
+ boolean isLoaded = true;
+ BitSet loadSet = sm.getLoaded();
+ if (attr != null) {
+ FieldMetaData fmd = sm.getMetaData().getField(attr);
+ // Could not find field metadata for the specified attribute.
+ if (fmd == null)
+ return LoadState.UNKNOWN;
+ // Otherwise, return the load state
+ if(!loadSet.get(fmd.getIndex()))
+ return LoadState.NOT_LOADED;
+ }
+ FieldMetaData[] fmds = sm.getMetaData().getFields();
+ // Check load state of all persistent eager fetch attributes
+ for (FieldMetaData fmd : fmds) {
+ if (fmd.isInDefaultFetchGroup()) {
+ if (!loadSet.get(fmd.getIndex())) {
+ isLoaded = false;
+ break;
+ }
+ // TODO: Complete contract for collections
+ }
+ }
+ return isLoaded ? LoadState.LOADED : LoadState.NOT_LOADED;
}
}