| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 1998, 2018 IBM Corporation. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| // 03/03/2010 - 2.1 Michael O'Brien |
| // - 302316: clear the object cache when testing stored procedure returns on SQLServer |
| // to avoid false positives visible only when debugging in DatabaseCall.buildOutputRow() |
| // - 260263: SQLServer 2005/2008 requires stored procedure creation select clause variable and column name matching |
| // 06/16/2010-2.2 Guy Pelletier |
| // - 247078: eclipselink-orm.xml schema should allow lob and enumerated on version and id mappings |
| // 09/03/2010-2.2 Guy Pelletier |
| // - 317286: DB column lenght not in sync between @Column and @JoinColumn |
| // 10/15/2010-2.2 Guy Pelletier |
| // - 322008: Improve usability of additional criteria applied to queries at the session/EM |
| // 10/27/2010-2.2 Guy Pelletier |
| // - 328114: @AttributeOverride does not work with nested embeddables having attributes of the same name |
| // 11/01/2010-2.2 Guy Pelletier |
| // - 322916: getParameter on Query throws NPE |
| // 08/07/2016-2.7 Dalia Abo Sheasha |
| // - 499335: Multiple embeddable fields can't reference same object |
| // 09/04/2018-3.0 Ravi Babu Tummuru |
| // - 538183: SETTING QUERYHINTS.CURSOR ON A NAMEDQUERY THROWS QUERYEXCEPTION |
| |
| package org.eclipse.persistence.testing.tests.jpa.advanced; |
| |
| import java.lang.reflect.Array; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.EnumSet; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Vector; |
| |
| import jakarta.persistence.CacheStoreMode; |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.FlushModeType; |
| import jakarta.persistence.Query; |
| import jakarta.persistence.metamodel.Attribute; |
| import jakarta.persistence.metamodel.Attribute.PersistentAttributeType; |
| import jakarta.persistence.metamodel.Bindable.BindableType; |
| import jakarta.persistence.metamodel.EntityType; |
| import jakarta.persistence.metamodel.MapAttribute; |
| import jakarta.persistence.metamodel.Metamodel; |
| import jakarta.persistence.metamodel.SingularAttribute; |
| import jakarta.persistence.metamodel.Type.PersistenceType; |
| import jakarta.persistence.spi.LoadState; |
| import jakarta.persistence.spi.ProviderUtil; |
| |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.persistence.annotations.BatchFetchType; |
| import org.eclipse.persistence.config.CascadePolicy; |
| import org.eclipse.persistence.config.HintValues; |
| import org.eclipse.persistence.config.QueryHints; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.descriptors.DescriptorEvent; |
| import org.eclipse.persistence.descriptors.DescriptorEventAdapter; |
| import org.eclipse.persistence.descriptors.invalidation.CacheInvalidationPolicy; |
| import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy; |
| import org.eclipse.persistence.expressions.Expression; |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.indirection.IndirectCollection; |
| import org.eclipse.persistence.indirection.IndirectContainer; |
| import org.eclipse.persistence.indirection.ValueHolderInterface; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.internal.helper.DatabaseField; |
| import org.eclipse.persistence.internal.helper.DatabaseTable; |
| import org.eclipse.persistence.internal.helper.Helper; |
| import org.eclipse.persistence.internal.indirection.DatabaseValueHolder; |
| import org.eclipse.persistence.internal.indirection.QueryBasedValueHolder; |
| import org.eclipse.persistence.history.AsOfClause; |
| import org.eclipse.persistence.internal.jpa.EJBQueryImpl; |
| import org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate; |
| import org.eclipse.persistence.internal.jpa.EntityManagerImpl; |
| import org.eclipse.persistence.internal.jpa.metamodel.MapAttributeImpl; |
| import org.eclipse.persistence.internal.jpa.metamodel.SingularAttributeImpl; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.jpa.JpaEntityManager; |
| import org.eclipse.persistence.jpa.JpaHelper; |
| import org.eclipse.persistence.jpa.PersistenceProvider; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| import org.eclipse.persistence.mappings.DirectCollectionMapping; |
| import org.eclipse.persistence.mappings.ForeignReferenceMapping; |
| import org.eclipse.persistence.mappings.ManyToManyMapping; |
| import org.eclipse.persistence.mappings.OneToManyMapping; |
| import org.eclipse.persistence.mappings.OneToOneMapping; |
| import org.eclipse.persistence.mappings.UnidirectionalOneToManyMapping; |
| import org.eclipse.persistence.queries.CursoredStream; |
| import org.eclipse.persistence.queries.DatabaseQuery; |
| import org.eclipse.persistence.queries.DoesExistQuery; |
| import org.eclipse.persistence.queries.ReadAllQuery; |
| import org.eclipse.persistence.sessions.DatabaseRecord; |
| import org.eclipse.persistence.sessions.Session; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| import org.eclipse.persistence.testing.framework.JoinedAttributeTestHelper; |
| import org.eclipse.persistence.testing.framework.QuerySQLTracker; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Bill; |
| import org.eclipse.persistence.testing.models.jpa.advanced.BillLine; |
| import org.eclipse.persistence.testing.models.jpa.advanced.BillLineItem; |
| import org.eclipse.persistence.testing.models.jpa.advanced.BillAction; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Address; |
| import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Bag; |
| import org.eclipse.persistence.testing.models.jpa.advanced.BarCode; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Buyer; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Cost; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Customer; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Dealer; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Department; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Door; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Employee; |
| import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator; |
| import org.eclipse.persistence.testing.models.jpa.advanced.EmploymentPeriod; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Equipment; |
| import org.eclipse.persistence.testing.models.jpa.advanced.EquipmentCode; |
| import org.eclipse.persistence.testing.models.jpa.advanced.GoldBuyer; |
| import org.eclipse.persistence.testing.models.jpa.advanced.HugeProject; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Jigsaw; |
| import org.eclipse.persistence.testing.models.jpa.advanced.JigsawPiece; |
| import org.eclipse.persistence.testing.models.jpa.advanced.LargeProject; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Loot; |
| import org.eclipse.persistence.testing.models.jpa.advanced.OrderedEntityA; |
| import org.eclipse.persistence.testing.models.jpa.advanced.OrderedEntityZ; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Oyster; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Pearl; |
| import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Product; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Project; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Quantity; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Room; |
| import org.eclipse.persistence.testing.models.jpa.advanced.SmallProject; |
| import org.eclipse.persistence.testing.models.jpa.advanced.ToDoList; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Violation; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Violation.ViolationID; |
| import org.eclipse.persistence.testing.models.jpa.advanced.ViolationCode; |
| import org.eclipse.persistence.testing.models.jpa.advanced.ViolationCode.ViolationCodeId; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Bolt; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Eater; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Nut; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Rabbit; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.RabbitFoot; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Sandwich; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.School; |
| import org.eclipse.persistence.testing.models.jpa.advanced.additionalcriteria.Student; |
| import org.eclipse.persistence.tools.schemaframework.SchemaManager; |
| import org.eclipse.persistence.tools.schemaframework.StoredFunctionDefinition; |
| import org.eclipse.persistence.exceptions.QueryException; |
| import org.junit.Assert; |
| import static org.junit.Assert.assertTrue; |
| |
| |
| /** |
| * This test suite tests EclipseLink JPA annotations extensions. |
| */ |
| public class AdvancedJPAJunitTest extends JUnitTestCase { |
| private static int empId; |
| private static int penelopeId; |
| private static int deptId; |
| private static int buyerId; |
| private static long visa = 1234567890; |
| private static long amex = 1987654321; |
| private static long diners = 1192837465; |
| private static long mastercard = 1647382910; |
| private static long rbc = 4783; |
| private static long scotia = 8732; |
| private static long td = 839362; |
| private static long cibc = 948274; |
| private static String newResponsibility = "The most useless responsibility ever."; |
| |
| public AdvancedJPAJunitTest() { |
| super(); |
| } |
| |
| public AdvancedJPAJunitTest(String name) { |
| super(name); |
| } |
| |
| @Override |
| public void setUp() { |
| super.setUp(); |
| clearCache(); |
| } |
| |
| public static Test suite() { |
| TestSuite suite = (TestSuite) suiteSpring(); |
| suite.addTest(new AdvancedJPAJunitTest("testTransparentIndirectionValueHolderSessionReset")); |
| suite.addTest(new AdvancedJPAJunitTest("testTransparentIndirectionQuerySessionReset")); |
| |
| if (!isJPA10()) { |
| suite.addTest(new AdvancedJPAJunitTest("testHistoryRelationshipQueryInitialization")); |
| } |
| |
| return suite; |
| } |
| |
| public static Test suiteSpring() { |
| TestSuite suite = new TestSuite(); |
| suite.setName("AdvancedJPAJunitTest"); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testSetup")); |
| suite.addTest(new AdvancedJPAJunitTest("testRelationshipReadDuringClone")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testExistenceCheckingSetting")); |
| suite.addTest(new AdvancedJPAJunitTest("testJoinColumnForeignKeyFieldLength")); |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeFetchWithAlias")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testJoinFetchAnnotation")); |
| suite.addTest(new AdvancedJPAJunitTest("testVerifyEmployeeCacheSettings")); |
| suite.addTest(new AdvancedJPAJunitTest("testVerifyEmployeeCustomizerSettings")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testUpdateEmployee")); |
| suite.addTest(new AdvancedJPAJunitTest("testVerifyUpdatedEmployee")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testCreateNewBuyer")); |
| suite.addTest(new AdvancedJPAJunitTest("testVerifyNewBuyer")); |
| suite.addTest(new AdvancedJPAJunitTest("testBuyerOptimisticLocking")); |
| suite.addTest(new AdvancedJPAJunitTest("testOptimisticLockExceptionOnMerge")); |
| suite.addTest(new AdvancedJPAJunitTest("testOptimisticLockExceptionOnMergeWithAssumeExists")); |
| suite.addTest(new AdvancedJPAJunitTest("testVersionUpdateForOwnedMappings")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testGiveFredAnObjectTypeConverterChange")); |
| suite.addTest(new AdvancedJPAJunitTest("testUpdatePenelopesPhoneNumberStatus")); |
| suite.addTest(new AdvancedJPAJunitTest("testRemoveJillWithPrivateOwnedPhoneNumbers")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testCreateNewEquipment")); |
| suite.addTest(new AdvancedJPAJunitTest("testAddNewEquipmentToDepartment")); |
| suite.addTest(new AdvancedJPAJunitTest("testRemoveDepartmentWithPrivateOwnedEquipment")); |
| suite.addTest(new AdvancedJPAJunitTest("testUpdateReadOnlyEquipmentCode")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQuery")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryByIndex")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryInOut")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryWithRawData")); |
| suite.addTest(new AdvancedJPAJunitTest("testModifyNamedStoredProcedureQueryWithRawData")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryWithResultSetMapping")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryWithResultSetFieldMapping")); |
| suite.addTest(new AdvancedJPAJunitTest("testNamedFunction")); |
| suite.addTest(new AdvancedJPAJunitTest("testNonTriggerLazyForSProc")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testMethodBasedTransformationMapping")); |
| suite.addTest(new AdvancedJPAJunitTest("testClassBasedTransformationMapping")); |
| suite.addTest(new AdvancedJPAJunitTest("testTransformationMappingWithColumnAnnotation")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testCursorStream")); |
| suite.addTest(new AdvancedJPAJunitTest("testCursoredNativeQueryDefinedViaAnnotation")); |
| suite.addTest(new AdvancedJPAJunitTest("testProperty")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testBackpointerOnMerge")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testUnidirectionalPersist")); |
| suite.addTest(new AdvancedJPAJunitTest("testUnidirectionalUpdate")); |
| suite.addTest(new AdvancedJPAJunitTest("testUnidirectionalFetchJoin")); |
| suite.addTest(new AdvancedJPAJunitTest("testUnidirectionalTargetLocking_AddRemoveTarget")); |
| suite.addTest(new AdvancedJPAJunitTest("testUnidirectionalTargetLocking_DeleteSource")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testMapBuildReferencesPKList")); |
| suite.addTest(new AdvancedJPAJunitTest("testListBuildReferencesPKList")); |
| suite.addTest(new AdvancedJPAJunitTest("testValuePKListMissingElement")); |
| suite.addTest(new AdvancedJPAJunitTest("testEnumeratedPrimaryKeys")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testAttributeOverrideToMultipleSameDefaultColumnName")); |
| suite.addTest(new AdvancedJPAJunitTest("testJoinFetchWithRefreshOnRelatedEntity")); |
| suite.addTest(new AdvancedJPAJunitTest("testSharedEmbeddedAttributeOverrides")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeToProjectWithBatchFetchTypeInReverseIteration")); |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeToProjectWithBatchFetchTypeInCustomIteration")); |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeToProjectWithBatchFetchTypeInRandomIteration")); |
| |
| if (!isJPA10()) { |
| // These tests use JPA 2.0 entity manager API |
| suite.addTest(new AdvancedJPAJunitTest("testQueryGetParameter")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaModelPopulate")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteria")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaWithParameterFromEM1")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaWithParameterFromEM2")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaWithParameterFromEMF")); |
| suite.addTest(new AdvancedJPAJunitTest("testComplexAdditionalCriteria")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaBetweenEntities")); |
| suite.addTest(new AdvancedJPAJunitTest("testAdditionalCriteriaWithSubQuery")); |
| |
| // Run this test only when the JPA 2.0 specification is enabled on the server, or we are in SE mode with JPA 2.0 capability |
| suite.addTest(new AdvancedJPAJunitTest("testMetamodelMinimalSanityTest")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testProjectToEmployeeWithBatchFetchJoinFetch")); |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeToPhoneNumberWithBatchFetchJoinFetch")); |
| suite.addTest(new AdvancedJPAJunitTest("testEmployeeToAddressWithBatchFetchJoinFetch")); |
| |
| suite.addTest(new AdvancedJPAJunitTest("testQueryJoinBasicCollectionTableUsingQueryResultsCache")); |
| suite.addTest(new AdvancedJPAJunitTest("testNullValueInCollectionWithOrderColumn")); |
| |
| // Bug 453865 |
| suite.addTest(new AdvancedJPAJunitTest("testJoinWithOrderByOnElementCollectionList")); |
| suite.addTest(new AdvancedJPAJunitTest("testJoinWithOrderByOnElementCollectionMap")); |
| } |
| |
| return suite; |
| } |
| |
| /** |
| * The setup is done as a test, both to record its failure, and to allow execution in the server. |
| */ |
| public void testSetup() { |
| ServerSession session = JUnitTestCase.getServerSession(); |
| new AdvancedTableCreator().replaceTables(session); |
| // The EquipmentCode class 'should' be set to read only. We want |
| // to be able to create a couple in the Employee populator, so |
| // force the read only to false. If EquipmentCode is not |
| // actually read only, don't worry, we set the original read |
| // only value back on the descriptor and the error will be |
| // caught in a later test in this suite. |
| ClassDescriptor descriptor = session.getDescriptor(EquipmentCode.class); |
| boolean shouldBeReadOnly = descriptor.shouldBeReadOnly(); |
| descriptor.setShouldBeReadOnly(false); |
| |
| // Populate the database with our examples. |
| EmployeePopulator employeePopulator = new EmployeePopulator(); |
| employeePopulator.buildExamples(); |
| employeePopulator.persistExample(session); |
| |
| descriptor.setShouldBeReadOnly(shouldBeReadOnly); |
| |
| clearCache(); |
| |
| //create stored function when database supports it |
| if (supportsStoredFunctions()) { |
| SchemaManager schema = new SchemaManager(session); |
| schema.replaceObject(buildStoredFunction()); |
| } |
| } |
| |
| public StoredFunctionDefinition buildStoredFunction() { |
| StoredFunctionDefinition func = new StoredFunctionDefinition(); |
| func.setName("StoredFunction_In"); |
| func.addArgument("P_IN", Long.class); |
| func.setReturnType(Long.class); |
| func.addStatement("RETURN P_IN * 1000"); |
| return func; |
| } |
| |
| /* Test named function 'StoredFunction_In'*/ |
| public void testNamedFunction() { |
| if (!supportsStoredFunctions()) { |
| warning("this test is not suitable for running on dbs that don't support stored function"); |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| Query query; |
| try { |
| query = em.createNamedQuery("StoredFunction_In"); |
| query.setParameter("P_IN", 1); |
| long result = (Long)query.getSingleResult(); |
| if (result != 1000L) { |
| fail("Incorrect result returned:" + result); |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 322916 |
| */ |
| public void testQueryGetParameter() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| Query query = em.createQuery("select e from Employee e where e.salary = :sal").setParameter("sal", 1000); |
| query.getParameter("sal"); |
| } catch (Exception e) { |
| fail("Get parameter on test failed: " + e); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test user defined additional criteria with no parameters. |
| */ |
| public void testAdditionalCriteriaModelPopulate() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| // Persist some schools |
| School school1 = new School(); |
| school1.setName("Ottawa Junior High"); |
| school1.addStudent(new Student("OttawaJRStud1")); |
| school1.addStudent(new Student("OttawaJRStud2")); |
| school1.addStudent(new Student("OttawaJRStud3")); |
| em.persist(school1); |
| |
| School school2 = new School(); |
| school2.setName("Ottawa Senior High"); |
| school2.addStudent(new Student("OttawaSRStud1")); |
| school2.addStudent(new Student("OttawaSRStud2")); |
| school2.addStudent(new Student("OttawaSRStud3")); |
| school2.addStudent(new Student("OttawaSRStud4")); |
| school2.addStudent(new Student("OttawaSRStud5")); |
| em.persist(school2); |
| |
| School school3 = new School(); |
| school3.setName("Toronto Junior High"); |
| school3.addStudent(new Student("TorontoJRStud1")); |
| school3.addStudent(new Student("TorontoJRStud2")); |
| school3.addStudent(new Student("TorontoJRStud3")); |
| school3.addStudent(new Student("TorontoJRStud4")); |
| school3.addStudent(new Student("TorontoJRStud5")); |
| school3.addStudent(new Student("TorontoJRStud6")); |
| school3.addStudent(new Student("TorontoJRStud7")); |
| em.persist(school3); |
| |
| School school4 = new School(); |
| school4.setName("Toronto Senior High"); |
| school4.addStudent(new Student("TorontoSRStud1")); |
| school4.addStudent(new Student("TorontoSRStud2")); |
| school4.addStudent(new Student("TorontoSRStud3")); |
| school4.addStudent(new Student("TorontoSRStud4")); |
| school4.addStudent(new Student("TorontoSRStud5")); |
| school4.addStudent(new Student("TorontoSRStud6")); |
| school4.addStudent(new Student("TorontoSRStud7")); |
| school4.addStudent(new Student("TorontoSRStud8")); |
| school4.addStudent(new Student("TorontoSRStud9")); |
| school4.addStudent(new Student("TorontoSRStud10")); |
| school4.addStudent(new Student("TorontoSRStud11")); |
| em.persist(school4); |
| |
| School school5 = new School(); |
| school5.setName("Montreal Senior High"); |
| school5.addStudent(new Student("MontrealSRStud1")); |
| school5.addStudent(new Student("MontrealSRStud2")); |
| school5.addStudent(new Student("MontrealSRStud3")); |
| school5.addStudent(new Student("MontrealSRStud4")); |
| school5.addStudent(new Student("MontrealSRStud5")); |
| em.persist(school5); |
| |
| Bolt bolt1 = new Bolt(); |
| Nut nut1 = new Nut(); |
| nut1.setColor("Grey"); |
| nut1.setSize(8); |
| bolt1.setNut(nut1); |
| em.persist(bolt1); |
| |
| Bolt bolt2 = new Bolt(); |
| Nut nut2 = new Nut(); |
| nut2.setColor("Black"); |
| nut2.setSize(8); |
| bolt2.setNut(nut2); |
| em.persist(bolt2); |
| |
| Bolt bolt3 = new Bolt(); |
| Nut nut3 = new Nut(); |
| nut3.setColor("Grey"); |
| nut3.setSize(6); |
| bolt3.setNut(nut3); |
| em.persist(bolt3); |
| |
| Bolt bolt4 = new Bolt(); |
| Nut nut4 = new Nut(); |
| nut4.setColor("Black"); |
| nut4.setSize(6); |
| bolt4.setNut(nut4); |
| em.persist(bolt4); |
| |
| Bolt bolt5 = new Bolt(); |
| Nut nut5 = new Nut(); |
| nut5.setColor("Grey"); |
| nut5.setSize(2); |
| bolt5.setNut(nut5); |
| em.persist(bolt5); |
| |
| Bolt bolt6 = new Bolt(); |
| Nut nut6 = new Nut(); |
| nut6.setColor("Grey"); |
| nut6.setSize(8); |
| bolt6.setNut(nut6); |
| em.persist(bolt6); |
| |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test user defined additional criteria with no parameters. The additional |
| * criteria on school filters for Ottawa named schools. |
| */ |
| public void testAdditionalCriteria() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| List schools = em.createNamedQuery("findJPQLSchools").getResultList(); |
| assertTrue("Incorrect number of schools were returned [" + schools.size() + "], expected [2]", schools.size() == 2); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test user defined additional criteria with parameter. |
| */ |
| public void testAdditionalCriteriaWithParameterFromEM1() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| // This should override the EMF property of Montreal% |
| em.setProperty("NAME", "Ottawa%"); |
| |
| // Find the schools, because of our additional criteria on Student |
| // and the property above, we should only return Ottawa students. |
| |
| List students = em.createQuery("SELECT s from Student s").getResultList(); |
| assertTrue("Incorrect number of students were returned [" + students.size() + "], expected [8]", students.size() == 8); |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test user defined additional criteria with parameter. |
| */ |
| public void testAdditionalCriteriaWithParameterFromEM2() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| // This should override the EMF property of Montreal% |
| em.setProperty("NAME", "Toronto%"); |
| |
| // Find the schools, because of our additional criteria on Student |
| // and the property above, we should only return Toronto students. |
| // However, they should not have any schools loaded. |
| |
| List students = em.createQuery("SELECT s from Student s").getResultList(); |
| assertTrue("Incorrect number of students were returned [" + students.size() + "], expected [18]", students.size() == 18); |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| public void testMapBuildReferencesPKList(){ |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| ClassDescriptor descriptor; |
| AbstractSession session = (AbstractSession) JpaHelper.getEntityManager(em).getActiveSession(); |
| descriptor = session.getDescriptorForAlias("ADV_DEPT"); |
| Department dept = (Department) em.createQuery("SELECT d FROM ADV_DEPT d WHERE d.equipment IS NOT EMPTY").getResultList().get(0); |
| ForeignReferenceMapping mapping = (ForeignReferenceMapping) descriptor.getMappingForAttributeName("equipment"); |
| Object[] pks = mapping.buildReferencesPKList(dept, mapping.getAttributeValueFromObject(dept), session); |
| assertTrue ("PK list is of incorrect size. pks.size: " + pks.length + " expected: " + (dept.getEquipment().size() * 2), pks.length == (dept.getEquipment().size() * 2)); |
| Map<Integer, Equipment> equipments = (Map<Integer, Equipment>) mapping.valueFromPKList(pks, null, session); |
| assertTrue("ValueFromPKList returned list of different size from actual entity.", equipments.size() == dept.getEquipment().size()); |
| for (Equipment equip : dept.getEquipment().values()){ |
| assertTrue("Equipment not found in ValueFromPKList list", equipments.containsKey(equip.getId())); |
| } |
| rollbackTransaction(em); |
| } |
| |
| public void testListBuildReferencesPKList(){ |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| Jigsaw jigsaw = new Jigsaw(); |
| for (int i = 1; i < 11; i++) { |
| jigsaw.addPiece(new JigsawPiece(i)); |
| } |
| em.persist(jigsaw); |
| |
| |
| em.flush(); |
| |
| clearCache(); |
| |
| AbstractSession session = (AbstractSession) JpaHelper.getEntityManager(em).getActiveSession(); |
| ClassDescriptor descriptor = session.getDescriptorForAlias("Jigsaw"); |
| |
| Jigsaw foundJigsaw = em.find(Jigsaw.class, jigsaw.getId()); |
| int expectedNumber = foundJigsaw.getPieces().size(); |
| |
| ForeignReferenceMapping mapping = (ForeignReferenceMapping) descriptor.getMappingForAttributeName("pieces"); |
| Object[] pks = mapping.buildReferencesPKList(foundJigsaw, mapping.getAttributeValueFromObject(foundJigsaw), session); |
| assertEquals("PK list is of incorrect size", expectedNumber, pks.length); |
| |
| List<JigsawPiece> elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, null, session); |
| assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size()); |
| |
| for (JigsawPiece element : elements){ |
| assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element)); |
| } |
| |
| elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, null, session); |
| assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size()); |
| |
| for (JigsawPiece element : elements){ |
| assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element)); |
| } |
| rollbackTransaction(em); |
| } |
| |
| public void testValuePKListMissingElement(){ |
| if (isOnServer()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| Jigsaw jigsaw = new Jigsaw(); |
| for (int i = 1; i < 11; i++) { |
| jigsaw.addPiece(new JigsawPiece(i)); |
| } |
| em.persist(jigsaw); |
| commitTransaction(em); |
| try { |
| |
| AbstractSession session = (AbstractSession) JpaHelper.getEntityManager(em).getActiveSession(); |
| ClassDescriptor descriptor = session.getDescriptorForAlias("Jigsaw"); |
| |
| Jigsaw foundJigsaw = em.find(Jigsaw.class, jigsaw.getId()); |
| int expectedNumber = foundJigsaw.getPieces().size(); |
| |
| OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("pieces"); |
| Object[] pks = mapping.buildReferencesPKList(foundJigsaw, mapping.getAttributeValueFromObject(foundJigsaw), session); |
| assertEquals("PK list is of incorrect size", expectedNumber, pks.length); |
| |
| session.getIdentityMapAccessor().invalidateObject(foundJigsaw.getPieces().get(2)); |
| DatabaseRecord fks = new DatabaseRecord(); |
| for (DatabaseField field : mapping.getSourceKeyFields()){ |
| fks.add(field, descriptor.getObjectBuilder().extractValueFromObjectForField(foundJigsaw, field, session)); |
| } |
| |
| mapping.writeFromObjectIntoRow(foundJigsaw, fks, session, DatabaseMapping.WriteType.UNDEFINED); |
| |
| List<JigsawPiece> elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, fks, session); |
| assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size()); |
| assertFalse("Collection contains unexpected null", elements.contains(null)); |
| for (JigsawPiece element : elements) { |
| assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element)); |
| } |
| em.refresh(foundJigsaw.getPieces().get(2)); |
| session.getIdentityMapAccessor().invalidateObject(foundJigsaw.getPieces().get(5)); |
| |
| elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, fks, session); |
| assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size()); |
| assertFalse("Collection contains unexpected null", elements.contains(null)); |
| for (JigsawPiece element : elements) { |
| assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element)); |
| } |
| |
| } finally { |
| try { |
| beginTransaction(em); |
| em.remove(jigsaw); |
| commitTransaction(em); |
| } catch (Exception e) { |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| } |
| |
| /** |
| * Test user defined additional criteria with parameters. |
| */ |
| public void testAdditionalCriteriaWithParameterFromEMF() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| // This should use the EMF NAME property of Montreal% |
| List students = em.createQuery("SELECT s from Student s").getResultList(); |
| assertTrue("Incorrect number of students were returned [" + students.size() + "], expected [5]", students.size() == 5); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test user defined additional criteria with parameter. |
| */ |
| public void testComplexAdditionalCriteria() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| em.setProperty("NUT_SIZE", 8); |
| em.setProperty("NUT_COLOR", "Grey"); |
| |
| List bolts = em.createQuery("SELECT b from Bolt b").getResultList(); |
| assertTrue("Incorrect number of bolts were returned [" + bolts.size() + "], expected [2]", bolts.size() == 2); |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test additional criteria when used on two entities that have a |
| * relationship between the two. |
| */ |
| public void testAdditionalCriteriaBetweenEntities() { |
| EntityManager em = createEntityManager("additional-criteria"); |
| |
| try { |
| beginTransaction(em); |
| |
| em.setProperty("SANDWICH_DESCRIPTION", "%hot%"); |
| em.setProperty("EATER_NAME", "%Glutton%"); |
| |
| Sandwich sandwich = new Sandwich(); |
| sandwich.setName("The Inferno"); |
| sandwich.setDescription("A hot and spicy crazy concoction"); |
| em.persist(sandwich); |
| |
| Eater eater = new Eater(); |
| eater.setName("Glutton for spicy"); |
| eater.setSandwhich(sandwich); |
| em.persist(eater); |
| |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test additional criteria when using a sub query. |
| */ |
| public void testAdditionalCriteriaWithSubQuery() { |
| EntityManager em = createEntityManager("additional-criteria"); |
| |
| try { |
| beginTransaction(em); |
| |
| Rabbit rabbit = new Rabbit(); |
| rabbit.setName("Bugs"); |
| em.persist(rabbit); |
| |
| RabbitFoot rabbitFoot = new RabbitFoot(); |
| rabbitFoot.setCaption("Caption of Bugs"); |
| rabbitFoot.setRabbitId(rabbit.getId()); |
| em.persist(rabbitFoot); |
| |
| commitTransaction(em); |
| |
| em.clear(); |
| clearCache("additional-criteria"); |
| |
| List<Eater> rabbits = em.createQuery("select this from Rabbit this").getResultList(); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 328114 |
| */ |
| public void testAttributeOverrideToMultipleSameDefaultColumnName() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| Loot loot = new Loot(); |
| Bag bag = new Bag(); |
| Quantity quantity = new Quantity(); |
| quantity.value = 11; |
| bag.quantity = quantity; |
| Cost cost = new Cost(); |
| cost.value = 5.99; |
| bag.cost = cost; |
| loot.bag = bag; |
| em.persist(loot); |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * This test performs minimal sanity testing on the advanced JPA model |
| * in order to verify metamodel creation.<p> |
| * See the metamodel test package suite for full regression tests. |
| * See SVN rev# 5124 |
| * http://fisheye2.atlassian.com/changelog/~author=mobrien/eclipselink/?cs=5124 |
| */ |
| public void testMetamodelMinimalSanityTest() { |
| EntityManager em = createEntityManager(); |
| // pre-clear metamodel to enable test reentry (SE only - not EE) |
| if(!isOnServer()) { |
| ((EntityManagerFactoryDelegate) em.getEntityManagerFactory()).setMetamodel(null); |
| } |
| Metamodel metamodel = em.getMetamodel(); |
| // get declared attributes |
| EntityType<LargeProject> entityLargeProject = metamodel.entity(LargeProject.class); |
| Set<Attribute<LargeProject, ?>> declaredAttributes = entityLargeProject.getDeclaredAttributes(); |
| assertTrue(declaredAttributes.size() > 0); // instead of a assertEquals(1, size) for future compatibility with changes to Buyer |
| |
| // check that getDeclaredAttribute and getDeclaredAttributes return the same attribute |
| Attribute<LargeProject, ?> budgetAttribute = entityLargeProject.getDeclaredAttribute("budget"); |
| assertNotNull(budgetAttribute); |
| Attribute<LargeProject, ?> budgetSingularAttribute = entityLargeProject.getDeclaredSingularAttribute("budget"); |
| assertNotNull(budgetSingularAttribute); |
| assertEquals(budgetSingularAttribute, budgetAttribute); |
| assertTrue(declaredAttributes.contains(budgetSingularAttribute)); |
| // check the type |
| Class<?> budgetClass = budgetSingularAttribute.getJavaType(); |
| // Verify whether we expect a boxed class or not |
| assertEquals(double.class, budgetClass); |
| //assertEquals(Double.class, budgetClass); |
| |
| // Test LargeProject.budget.buyingDays |
| |
| // Check an EnumSet on an Entity |
| EntityType<Buyer> entityBuyer = metamodel.entity(Buyer.class); |
| // public enum Weekdays { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } |
| // private EnumSet<Weekdays> buyingDays; |
| assertNotNull(entityBuyer); |
| // check persistence type |
| assertEquals(PersistenceType.ENTITY, entityBuyer.getPersistenceType()); |
| assertEquals(Buyer.class, entityBuyer.getJavaType()); |
| // verify EnumSet is a SingularAttribute |
| Attribute<? super Buyer, ?> buyingDaysAttribute = entityBuyer.getAttribute("buyingDays"); |
| assertNotNull(buyingDaysAttribute); |
| // Check persistent attribute type |
| assertEquals(PersistentAttributeType.BASIC, buyingDaysAttribute.getPersistentAttributeType()); |
| // Non-spec check on the attribute impl type |
| // EnumSet is not a Set in the Metamodel - it is a treated as a BasicType single object (SingularAttributeType) |
| // BasicTypeImpl@8980685:EnumSet [ javaType: class java.util.EnumSet] |
| assertFalse(((SingularAttributeImpl)buyingDaysAttribute).isPlural()); |
| BindableType buyingDaysElementBindableType = ((SingularAttributeImpl)buyingDaysAttribute).getBindableType(); |
| assertEquals(BindableType.SINGULAR_ATTRIBUTE, buyingDaysElementBindableType); |
| SingularAttribute<? super Buyer, EnumSet> buyingDaysSingularAttribute = entityBuyer.getSingularAttribute("buyingDays", EnumSet.class); |
| assertNotNull(buyingDaysSingularAttribute); |
| assertFalse(buyingDaysSingularAttribute.isCollection()); |
| |
| // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_74:_20090909:_Implement_IdentifiableType.hasSingleIdAttribute.28.29 |
| // Check for Id that exists |
| boolean expectedIAExceptionThrown = false; |
| boolean hasSingleIdAttribute = false; |
| try { |
| hasSingleIdAttribute = entityBuyer.hasSingleIdAttribute(); |
| } catch (IllegalArgumentException iae) { |
| //iae.printStackTrace(); |
| expectedIAExceptionThrown = true; |
| } |
| assertFalse(expectedIAExceptionThrown); |
| assertTrue(hasSingleIdAttribute); |
| |
| // Verify that the BasicMap Buyer.creditCards is picked up properly |
| //* @param <X> The type the represented Map belongs to |
| //* @param <K> The type of the key of the represented Map |
| //* @param <V> The type of the value of the represented Map |
| //public class MapAttributeImpl<X, K, V> extends PluralAttributeImpl<X, java.util.Map<K, V>, V> |
| Attribute<? super Buyer, ?> buyerCreditCards = entityBuyer.getAttribute("creditCards"); |
| assertNotNull(buyerCreditCards); |
| assertTrue(buyerCreditCards.isCollection()); |
| assertTrue(buyerCreditCards instanceof MapAttributeImpl); |
| MapAttribute<? super Buyer, ?, ?> buyerCreditCardsMap = entityBuyer.getMap("creditCards"); |
| |
| // Verify owning type |
| assertNotNull(buyerCreditCardsMap); |
| assertEquals(entityBuyer, buyerCreditCardsMap.getDeclaringType()); |
| |
| // Verify Map Key |
| assertEquals(String.class, buyerCreditCardsMap.getKeyJavaType()); |
| |
| // Verify Map Value |
| assertEquals(Long.class, buyerCreditCardsMap.getElementType().getJavaType()); |
| } |
| |
| /** |
| * Verifies that existence-checking metadata is correctly processed. |
| */ |
| public void testExistenceCheckingSetting() { |
| ServerSession session = JUnitTestCase.getServerSession(); |
| |
| ClassDescriptor employeeDescriptor = session.getDescriptor(Employee.class); |
| assertTrue("Employee existence checking was incorrect", employeeDescriptor.getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.CheckDatabase); |
| |
| ClassDescriptor projectDescriptor = session.getDescriptor(Project.class); |
| assertTrue("Project existence checking was incorrect", projectDescriptor.getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.CheckCache); |
| |
| ClassDescriptor smallProjectDescriptor = session.getDescriptor(SmallProject.class); |
| assertTrue("SmallProject existence checking was incorrect", smallProjectDescriptor.getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.AssumeExistence); |
| |
| ClassDescriptor largeProjectDescriptor = session.getDescriptor(LargeProject.class); |
| assertTrue("LargeProject existence checking was incorrect", largeProjectDescriptor.getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.AssumeNonExistence); |
| } |
| |
| public void testJoinColumnForeignKeyFieldLength() { |
| ServerSession session = JUnitTestCase.getServerSession(); |
| |
| ClassDescriptor employeeDescriptor = session.getDescriptor(Employee.class); |
| ClassDescriptor buyerDescriptor = session.getDescriptor(Buyer.class); |
| |
| //////////////////// Test fk from a secondary table //////////////////// |
| DatabaseTable secondaryTable = employeeDescriptor.getTable("CMP3_SALARY"); |
| Map<DatabaseField, DatabaseField> keys = employeeDescriptor.getAdditionalTablePrimaryKeyFields().get(secondaryTable); |
| |
| for (DatabaseField pkField : keys.keySet()) { |
| DatabaseField fkField = keys.get(pkField); |
| assertTrue("The secondary table foreign field [" + fkField.getName() + "(" + fkField.getLength() + ")] did not have the same length as the primary key field [" + pkField.getName() + "(" + pkField.getLength() + ")]", fkField.getLength() == pkField.getLength()); |
| } |
| |
| ////////////////////////// Test a M-1 mapping ////////////////////////// |
| DatabaseMapping mapping = employeeDescriptor.getMappingForAttributeName("address"); |
| assertNotNull("The address mapping from Employee was not found", mapping); |
| assertTrue("The address mapping is no longer a one to one mapping", mapping.isOneToOneMapping()); |
| |
| keys = ((OneToOneMapping) mapping).getSourceToTargetKeyFields(); |
| |
| for (DatabaseField fkField : keys.keySet()) { |
| DatabaseField pkField = keys.get(fkField); |
| assertTrue("The address mapping foreign field [" + fkField.getName() + "(" + fkField.getLength() + ")] did not have the same length as the primary key field [" + pkField.getName() + "(" + pkField.getLength() + ")]", fkField.getLength() == pkField.getLength()); |
| } |
| |
| ////////////////// Test a unidirectional 1-M mapping /////////////////// |
| mapping = employeeDescriptor.getMappingForAttributeName("dealers"); |
| assertNotNull("The dealers mapping from Employee was not found", mapping); |
| assertTrue("The dealers mapping is no longer a unidirectional one to many mapping", mapping.isUnidirectionalOneToManyMapping()); |
| |
| keys = ((UnidirectionalOneToManyMapping) mapping).getTargetForeignKeysToSourceKeys(); |
| |
| for (DatabaseField fkField : keys.keySet()) { |
| DatabaseField pkField = keys.get(fkField); |
| assertTrue("The dealers mapping foreign key field [" + fkField.getName() + "(" + fkField.getLength() + ")] did not have the same length as the primary key field [" + pkField.getName() + "(" + pkField.getLength() + ")]", fkField.getLength() == pkField.getLength()); |
| } |
| |
| ////////////////////////// Test a M-M mapping ////////////////////////// |
| mapping = employeeDescriptor.getMappingForAttributeName("projects"); |
| assertNotNull("The projects mapping from Employee was not found", mapping); |
| assertTrue("The projects mapping is no longer a many to many mapping", mapping.isManyToManyMapping()); |
| |
| Vector<DatabaseField> sourceKeys = ((ManyToManyMapping) mapping).getSourceKeyFields(); |
| Vector<DatabaseField> sourceRelationKeys = ((ManyToManyMapping) mapping).getSourceRelationKeyFields(); |
| |
| for (int i = 0; i < sourceKeys.size(); i++) { |
| DatabaseField sourcePrimaryKey = sourceKeys.get(i); |
| DatabaseField sourceRelationForeignKey = sourceRelationKeys.get(i); |
| |
| assertTrue("The projects mapping source relation foreign key field [" + sourceRelationForeignKey.getName() + "(" + sourceRelationForeignKey.getLength() + ")] did not have the same length as the source primary key field [" + sourcePrimaryKey.getName() + "(" + sourcePrimaryKey.getLength() + ")]", sourcePrimaryKey.getLength() == sourceRelationForeignKey.getLength()); |
| } |
| |
| Vector<DatabaseField> targetKeys = ((ManyToManyMapping) mapping).getSourceKeyFields(); |
| Vector<DatabaseField> targetRelationKeys = ((ManyToManyMapping) mapping).getSourceRelationKeyFields(); |
| |
| for (int i = 0; i < targetKeys.size(); i++) { |
| DatabaseField targetPrimaryKey = targetKeys.get(i); |
| DatabaseField targetRelationForeignKey = targetRelationKeys.get(i); |
| |
| assertTrue("The projects mapping target relation foreign key field [" + targetRelationForeignKey.getName() + "(" + targetRelationForeignKey.getLength() + ")] did not have the same length as the target primary key field [" + targetPrimaryKey.getName() + "(" + targetPrimaryKey.getLength() + ")]", targetPrimaryKey.getLength() == targetRelationForeignKey.getLength()); |
| } |
| |
| //////////////////////// Test a basic collection /////////////////////// |
| mapping = employeeDescriptor.getMappingForAttributeName("responsibilities"); |
| assertNotNull("The responsibilities mapping from Employee was not found", mapping); |
| assertTrue("The responsibilities mapping is no longer a direct collection mapping", mapping.isDirectCollectionMapping()); |
| |
| Vector<DatabaseField> primaryKeys = ((DirectCollectionMapping) mapping).getSourceKeyFields(); |
| Vector<DatabaseField> foreignKeys = ((DirectCollectionMapping) mapping).getReferenceKeyFields(); |
| |
| for (int i = 0; i < primaryKeys.size(); i++) { |
| DatabaseField primaryKey = primaryKeys.get(i); |
| DatabaseField foreignKey = foreignKeys.get(i); |
| |
| assertTrue("The responsibilities mapping foreign key field [" + foreignKey.getName() + "(" + foreignKey.getLength() + ")] did not have the same length as the source primary key field [" + primaryKey.getName() + "(" + primaryKey.getLength() + ")]", primaryKey.getLength() == foreignKey.getLength()); |
| } |
| |
| //////// Test an element collection mapping (direct collection) //////// |
| mapping = buyerDescriptor.getMappingForAttributeName("creditLines"); |
| assertNotNull("The creditLines mapping from Buyer was not found", mapping); |
| assertTrue("The creditLines mapping is no longer an element collection mapping", mapping.isDirectCollectionMapping()); |
| |
| primaryKeys = ((DirectCollectionMapping) mapping).getSourceKeyFields(); |
| foreignKeys = ((DirectCollectionMapping) mapping).getReferenceKeyFields(); |
| |
| for (int i = 0; i < primaryKeys.size(); i++) { |
| DatabaseField primaryKey = primaryKeys.get(i); |
| DatabaseField foreignKey = foreignKeys.get(i); |
| |
| assertTrue("The creditLines mapping foreign key field [" + foreignKey.getName() + "(" + foreignKey.getLength() + ")] did not have the same length as the source primary key field [" + primaryKey.getName() + "(" + primaryKey.getLength() + ")]", primaryKey.getLength() == foreignKey.getLength()); |
| } |
| |
| // Items not directly tested: element collection using a map and basic map. |
| } |
| |
| /** |
| * Verifies that settings from the Employee cache annotation have been set. |
| */ |
| public void testVerifyEmployeeCacheSettings() { |
| EntityManager em = createEntityManager("default1"); |
| ClassDescriptor descriptor; |
| if (isOnServer()) { |
| descriptor = getServerSession("default1").getDescriptorForAlias("Employee"); |
| } else { |
| descriptor = ((EntityManagerImpl) em).getServerSession().getDescriptorForAlias("Employee"); |
| } |
| |
| if (descriptor == null) { |
| fail("A descriptor for the Employee alias was not found in the default1 PU."); |
| } else { |
| assertTrue("Incorrect cache type() setting.", descriptor.getIdentityMapClass().equals(ClassConstants.SoftCacheWeakIdentityMap_Class)); |
| assertTrue("Incorrect cache size() setting, was: " + descriptor.getIdentityMapSize() + " expected: 730.", descriptor.getIdentityMapSize() == 730); |
| assertFalse("Incorrect cache isolated() setting.", descriptor.isIsolated()); |
| assertFalse("Incorrect cache alwaysRefresh() setting.", descriptor.shouldAlwaysRefreshCache()); |
| |
| // The diableHits() setting gets changed in the employee customizer. |
| // Its setting is checked in the test below. |
| |
| CacheInvalidationPolicy policy = descriptor.getCacheInvalidationPolicy(); |
| assertTrue("Incorrect cache expiry() policy setting.", policy instanceof TimeToLiveCacheInvalidationPolicy); |
| assertTrue("Incorrect cache expiry() setting.", ((TimeToLiveCacheInvalidationPolicy) policy).getTimeToLive() == 1000000); |
| |
| assertTrue("Incorrect cache coordinationType() settting.", descriptor.getCacheSynchronizationType() == ClassDescriptor.INVALIDATE_CHANGED_OBJECTS); |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Verifies that settings from the EmployeeCustomizer have been set. |
| */ |
| public void testVerifyEmployeeCustomizerSettings() { |
| EntityManager em = createEntityManager(); |
| |
| ClassDescriptor descriptor = getServerSession().getDescriptorForAlias("Employee"); |
| |
| if (descriptor == null) { |
| fail("A descriptor for the Employee alias was not found."); |
| } else { |
| assertFalse("Disable cache hits was true. Customizer should have made it false.", descriptor.shouldDisableCacheHits()); |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Verifies that the join-fetch annotation was read correctly. |
| */ |
| public void testJoinFetchAnnotation() { |
| ServerSession session = JUnitTestCase.getServerSession(); |
| ClassDescriptor descriptor = session.getDescriptor(Employee.class); |
| if (((ForeignReferenceMapping)descriptor.getMappingForAttributeName("department")).getJoinFetch() != ForeignReferenceMapping.OUTER_JOIN) { |
| fail("JoinFetch annotation not read correctly for Employee.department."); |
| } |
| } |
| |
| /** |
| * Tests: |
| * - BasicCollection mapping |
| * - Serialized Basic of type EnumSet. |
| * - BasicCollection that uses an Enum converter (by detection). |
| */ |
| public void testUpdateEmployee() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllSQLEmployees"); |
| Collection<Employee> employees = query.getResultCollection(); |
| |
| if (employees.isEmpty()) { |
| fail("No Employees were found. Test requires at least one Employee to be created in the EmployeePopulator."); |
| } else { |
| Employee emp = employees.iterator().next(); |
| emp.addResponsibility(newResponsibility); |
| emp.setMondayToFridayWorkWeek(); |
| empId = emp.getId(); |
| commitTransaction(em); |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Verifies: |
| * - a BasicCollection mapping. |
| * - a BasicCollection that uses an Enum converter (by detection). |
| */ |
| public void testVerifyUpdatedEmployee() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Employee emp = em.find(Employee.class, empId); |
| |
| assertNotNull("The updated employee was not found.", emp); |
| |
| boolean found = false; |
| for (String responsibility : (Collection<String>) emp.getResponsibilities()) { |
| if (responsibility.equals(newResponsibility)) { |
| found = true; |
| break; |
| } |
| } |
| commitTransaction(em); |
| assertTrue("The new responsibility was not added.", found); |
| assertTrue("The basic collection using enums was not persisted correctly.", emp.worksMondayToFriday()); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| public void testVersionUpdateForOwnedMappings(){ |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Employee emp = em.find(Employee.class, empId); |
| int currentVersion = emp.getVersion(); |
| assertNotNull("The employee was not found for Id.", empId); |
| |
| emp.getResponsibilities().add("UpdateVersionField"); |
| commitTransaction(em); |
| assertTrue("Did not increment version for change to direct collection", emp.getVersion() == ++currentVersion); |
| beginTransaction(em); |
| emp = em.find(Employee.class, empId); |
| emp.getDealers().add(em.merge(new Dealer("update", "version"))); |
| commitTransaction(em); |
| assertTrue("Did not increment version for change to uni-directional one to many with join table", emp.getVersion() == ++currentVersion); |
| beginTransaction(em); |
| emp = em.find(Employee.class, empId); |
| emp.getProjects().add(em.merge(new LargeProject("versionUpdate"))); |
| commitTransaction(em); |
| assertTrue("Did not increment version for change to owned ManyToMany", emp.getVersion() == ++currentVersion); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests: |
| * - BasicMap mapping with a TypeConverter on the map value and an |
| * ObjectTypeConverter on the map key. |
| * - Basic with a custom converter |
| * - Serialized Basic of type EnumSet. |
| */ |
| public void testCreateNewBuyer() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| GoldBuyer buyer = new GoldBuyer(); |
| |
| buyer.setName("Guy Pelletier"); |
| buyer.setGender("Made of testosterone"); |
| buyer.setDescription("Loves to spend"); |
| |
| buyer.addVisa(visa); |
| buyer.addAmex(amex); |
| buyer.addDinersClub(diners); |
| buyer.addMastercard(mastercard); |
| |
| buyer.addRoyalBankCreditLine(rbc); |
| buyer.addScotiabankCreditLine(scotia); |
| buyer.addTorontoDominionCreditLine(td); |
| buyer.addCanadianImperialCreditLine(cibc); |
| |
| buyer.setSaturdayToSundayBuyingDays(); |
| |
| em.persist(buyer); |
| commitTransaction(em); |
| buyerId = buyer.getId(); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Verifies: |
| * - BasicMap mapping with a TypeConverter on the map value and an |
| * ObjectTypeConverter on the map key. |
| * - Basic with a custom converter |
| * - Serialized Basic of type EnumSet. |
| */ |
| public void testVerifyNewBuyer() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| GoldBuyer buyer = em.find(GoldBuyer.class, buyerId); |
| |
| assertNotNull("The new buyer was not found", buyer); |
| assertTrue("Gender was not persisted correctly.", buyer.isMale()); |
| assertTrue("Visa card did not persist correctly.", buyer.hasVisa(visa)); |
| assertTrue("Amex card did not persist correctly.", buyer.hasAmex(amex)); |
| assertTrue("Diners Club card did not persist correctly.", buyer.hasDinersClub(diners)); |
| assertTrue("Mastercard card did not persist correctly.", buyer.hasMastercard(mastercard)); |
| |
| assertTrue("RBC credit line did not persist correctly.", buyer.hasRoyalBankCreditLine(rbc)); |
| assertTrue("Scotia credit line did not persist correctly.", buyer.hasScotiabankCreditLine(scotia)); |
| assertTrue("TD credit line did not persist correctly.", buyer.hasTorontoDominionCreditLine(td)); |
| assertTrue("CIBC credit line did not persist correctly.", buyer.hasCanadianImperialCreditLine(cibc)); |
| |
| assertTrue("The serialized enum set was not persisted correctly.", buyer.buysSaturdayToSunday()); |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests an OptimisticLocking policy set on Buyer. |
| */ |
| public void testBuyerOptimisticLocking() { |
| // Cannot create parallel entity managers in the server. |
| if (isOnServer()) { |
| return; |
| } |
| |
| EntityManager em1 = createEntityManager(); |
| EntityManager em2 = createEntityManager(); |
| em1.getTransaction().begin(); |
| em2.getTransaction().begin(); |
| RuntimeException caughtException = null; |
| try { |
| GoldBuyer buyer1 = em1.find(GoldBuyer.class, buyerId); |
| GoldBuyer buyer2 = em2.find(GoldBuyer.class, buyerId); |
| |
| buyer1.setName("Geezer"); |
| buyer2.setName("Guyzer"); |
| // Uses field locking, so need to update version. |
| buyer1.setVersion(buyer1.getVersion() + 1); |
| buyer2.setVersion(buyer2.getVersion() + 1); |
| |
| em1.getTransaction().commit(); |
| em2.getTransaction().commit(); |
| |
| em1.close(); |
| em2.close(); |
| } catch (RuntimeException e) { |
| caughtException = e; |
| if (em1.getTransaction().isActive()){ |
| em1.getTransaction().rollback(); |
| } |
| |
| if (em2.getTransaction().isActive()){ |
| em2.getTransaction().rollback(); |
| } |
| |
| em1.close(); |
| em2.close(); |
| } |
| if (caughtException == null) { |
| fail("Optimistic lock exception was not thrown."); |
| } else if (!(caughtException.getCause() instanceof jakarta.persistence.OptimisticLockException)) { |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw caughtException; |
| } |
| } |
| |
| /** |
| * Tests an ObjectTypeConverter on a direct to field mapping. |
| */ |
| public void testGiveFredAnObjectTypeConverterChange() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllEmployeesByFirstName"); |
| query.setParameter("firstname", "Fred"); |
| Collection<Employee> employees = query.getResultCollection(); |
| |
| if (employees.isEmpty()) { |
| fail("No employees named Fred were found. Test requires at least one Fred to be created in the EmployeePopulator."); |
| } else { |
| Employee fred = employees.iterator().next(); |
| fred.setFemale(); |
| fred.setFirstName("Penelope"); |
| penelopeId = fred.getId(); |
| |
| commitTransaction(em); |
| |
| // Clear cache and clear the entity manager |
| clearCache(); |
| em.clear(); |
| |
| Employee penelope = em.find(Employee.class, penelopeId); |
| assertTrue("Fred's ObjectTypeConverter change to Penelope didn't occur.", penelope.isFemale()); |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a BasicCollection on an entity that uses a composite primary key. |
| */ |
| public void testUpdatePenelopesPhoneNumberStatus() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Employee emp = em.find(Employee.class, penelopeId); |
| assertNotNull("The employee with id: [" + penelopeId + "] was not found.", emp); |
| |
| for (PhoneNumber phoneNumber : emp.getPhoneNumbers()) { |
| phoneNumber.addStatus(PhoneNumber.PhoneStatus.ACTIVE); |
| phoneNumber.addStatus(PhoneNumber.PhoneStatus.ASSIGNED); |
| } |
| |
| commitTransaction(em); |
| |
| // Clear cache and clear the entity manager |
| clearCache(); |
| em.clear(); |
| |
| Employee emp2 = em.find(Employee.class, penelopeId); |
| |
| for (PhoneNumber phone : emp2.getPhoneNumbers()) { |
| assertTrue("", phone.getStatus().contains(PhoneNumber.PhoneStatus.ACTIVE)); |
| assertTrue("", phone.getStatus().contains(PhoneNumber.PhoneStatus.ASSIGNED)); |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Test that an embedded attribute can correctly share a field override with |
| * its parent class and write a non-null value when it is inserted and then modified. |
| * EL Bug 393520 |
| */ |
| public void testSharedEmbeddedAttributeOverrides() { |
| EntityManager em = createEntityManager(); |
| try { |
| Product product = new Product(); |
| product.setName("Scottish Shortbread" ); |
| product.setCountryCode("GBR"); |
| product.setBarCode1(new BarCode("123-456-789", "GBR")); |
| product.setBarCode2(null); |
| |
| beginTransaction(em); |
| em.persist(product); |
| commitTransaction(em); |
| |
| Product productReRead = em.find(Product.class, product.getId()); |
| productReRead.setName("Beef Jerky"); |
| productReRead.setCountryCode("USA"); |
| productReRead.setBarCode1(new BarCode("722-666-489", "USA")); |
| productReRead.setBarCode2(null); |
| |
| beginTransaction(em); |
| em.merge(productReRead); |
| commitTransaction(em); |
| |
| Product productReRead2 = em.find(Product.class, product.getId()); |
| productReRead2.setName("OREO"); |
| productReRead2.setCountryCode("USA"); |
| String oreoCodeNumber = "762-230-051"; |
| BarCode barcode = new BarCode(oreoCodeNumber, "USA"); |
| productReRead2.setBarCode1(barcode); |
| productReRead2.setBarCode2(barcode); |
| |
| beginTransaction(em); |
| em.merge(productReRead2); |
| commitTransaction(em); |
| |
| Product oreoProduct = em.find(Product.class, product.getId()); |
| BarCode oreoBarCode1 = oreoProduct.getBarCode1(); |
| BarCode oreoBarCode2 = oreoProduct.getBarCode2(); |
| assertEquals(oreoCodeNumber, oreoBarCode1.getCodeNumber()); |
| assertEquals(oreoCodeNumber, oreoBarCode2.getCodeNumber()); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| throw e; |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Remove an object from the shared cache as if garbage collected |
| * NPE will occur when it is read in using the CacheStoreMode.BYPASS setting outside a transaction. |
| */ |
| public void testReadingEntityGarbageCollectedFromSharedCache(){ |
| EntityManager em = createEntityManager(); |
| Employee emp = (Employee)em.createQuery("Select e from Employee e").getResultList().get(0); |
| em.clear(); |
| clearCache(); |
| // CacheKey key = this.getServerSession().getIdentityMapAccessorInstance().getCacheKeyForObject(emp); |
| // key.setObject(null); |
| try{ |
| //query for the shared object that has a cachekey but was garbage collected from the shared cache |
| Query q = em.createQuery("Select f from Employee f where f.id ="+emp.getId()); |
| //only seems to reproduce with this setting and not in an early transaction |
| q.setHint(QueryHints.CACHE_STORE_MODE, CacheStoreMode.BYPASS); |
| try { |
| Employee clone = (Employee)q.getSingleResult(); |
| clone.toString(); |
| }catch (java.lang.NullPointerException e){ |
| fail("NPE occured building an Entity whos reference in the shared cache was garbage collected: "+e); |
| } |
| }finally { |
| if (this.isTransactionActive(em)) { |
| this.rollbackTransaction(em); |
| } |
| getServerSession().getIdentityMapAccessorInstance().initializeAllIdentityMaps(); |
| } |
| } |
| |
| |
| /** |
| * Tests a @PrivateOwned @OneToMany mapping. |
| */ |
| public void testRemoveJillWithPrivateOwnedPhoneNumbers() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllEmployeesByFirstName"); |
| query.setParameter("firstname", "Jill"); |
| Collection<Employee> employees = query.getResultCollection(); |
| |
| if (employees.isEmpty()) { |
| fail("No employees named Jill were found. Test requires at least one Jill to be created in the EmployeePopulator."); |
| } else { |
| Employee jill = employees.iterator().next(); |
| Collection<PhoneNumber> phoneNumbers = jill.getPhoneNumbers(); |
| |
| if (phoneNumbers.isEmpty()) { |
| fail("Jill does not have any phone numbers. Test requires that Jill have atleast one phone number created in the EmployeePopulator."); |
| } |
| |
| // Re-assign her managed employees and remove from her list. |
| for (Employee employee : jill.getManagedEmployees()) { |
| employee.setManager(jill.getManager()); |
| } |
| jill.getManagedEmployees().clear(); |
| |
| int jillId = jill.getId(); |
| |
| em.remove(jill); |
| commitTransaction(em); |
| |
| assertNull("Jill herself was not removed.", em.find(Employee.class, jillId)); |
| |
| for (PhoneNumber phoneNumber : phoneNumbers) { |
| assertNull("Jill's phone numbers were not deleted.", em.find(PhoneNumber.class, phoneNumber.buildPK())); |
| } |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Creates some new equipment objects. |
| */ |
| public void testCreateNewEquipment() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| // Persist some equipment. |
| Equipment equip1 = new Equipment(); |
| equip1.setDescription("Toaster"); |
| em.persist(equip1); |
| |
| Equipment equip2 = new Equipment(); |
| equip1.setDescription("Bucket"); |
| em.persist(equip2); |
| |
| Equipment equip3 = new Equipment(); |
| equip1.setDescription("Broom"); |
| em.persist(equip3); |
| |
| commitTransaction(em); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests adding objects to a 1-M mapping that uses a map. |
| */ |
| public void testAddNewEquipmentToDepartment() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllSQLEquipment"); |
| Collection<Equipment> equipment = query.getResultCollection(); |
| |
| if (equipment.isEmpty()) { |
| fail("No Equipment was found. testCreateNewEquipment should have created new equipment and should have run before this test."); |
| } else { |
| Department department = new Department(); |
| department.setName("Department with equipment"); |
| |
| for (Equipment e : equipment) { |
| department.addEquipment(e); |
| } |
| |
| em.persist(department); |
| deptId = department.getId(); |
| commitTransaction(em); |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests that backpointers are not changed after a merge operation. |
| */ |
| public void testBackpointerOnMerge() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| |
| // create a new department |
| Department department = new Department(); |
| department.setName("Football"); |
| // persist the department |
| em.persist(department); |
| commitTransaction(em); |
| closeEntityManager(em); |
| |
| // add equipment to the department |
| em = createEntityManager(); |
| beginTransaction(em); |
| Equipment equipment = new Equipment(); |
| equipment.setDescription("Shields & Dummies"); |
| department.addEquipment(equipment); |
| em.merge(department); |
| commitTransaction(em); |
| closeEntityManager(em); |
| |
| assertTrue(department.getEquipment().get(0) == equipment); |
| assertEquals(System.identityHashCode(department.getEquipment().get(0)), System.identityHashCode(equipment)); |
| assertEquals(department.getId(), equipment.getDepartment().getId()); |
| assertTrue("The department instance (backpointer) from equipment was modified after merge.", department == equipment.getDepartment()); |
| assertEquals("The department instance (backpointer) from equipment was modified after merge.", System.identityHashCode(department), System.identityHashCode(equipment.getDepartment())); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw e; |
| } |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery. |
| */ |
| public void testNamedStoredProcedureQuery() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later |
| em.clear(); |
| |
| Address address2 = (Address) em.createNamedQuery("SProcAddress").setParameter("ADDRESS_ID", address1.getID()).getSingleResult(); |
| assertNotNull("Address returned from stored procedure is null", address2); |
| assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new |
| assertTrue("Address build correctly using stored procedure", (address2.getID() == address1.getID())); |
| assertTrue("Address build correctly using stored procedure", (address2.getStreet().equals(address1.getStreet()))); |
| assertTrue("Address build correctly using stored procedure", (address2.getCountry().equals(address1.getCountry()))); |
| assertTrue("Address build correctly using stored procedure", (address2.getProvince().equals(address1.getProvince()))); |
| |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery using indexed parameters. |
| */ |
| public void testNamedStoredProcedureQueryByIndex() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later |
| em.clear(); |
| |
| Address address2 = (Address) em.createNamedQuery("SProcAddressByIndex").setParameter("ADDRESS_ID", address1.getID()).getSingleResult(); |
| assertNotNull("Address returned from stored procedure is null", address2); |
| assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new |
| assertTrue("Address build correctly using stored procedure", (address2.getID() == address1.getID())); |
| assertTrue("Address build correctly using stored procedure", (address2.getStreet().equals(address1.getStreet()))); |
| assertTrue("Address build correctly using stored procedure", (address2.getCountry().equals(address1.getCountry()))); |
| assertTrue("Address build correctly using stored procedure", (address2.getProvince().equals(address1.getProvince()))); |
| |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery using a result-set mapping. |
| * 304400: Note: this test does not actually test a ResultSet return - it uses output parameters. |
| * To enable ResultSet testing - set returnsResultSet=true via orm.xml, annotation or via program call like the the core tests. |
| */ |
| public void testNamedStoredProcedureQueryWithResultSetMapping() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later |
| em.clear(); |
| |
| Address address2 = (Address) em.createNamedQuery("SProcAddressWithResultSetMapping").setParameter("address_id_v", address1.getID()).getSingleResult(); |
| assertNotNull("Address returned from stored procedure is null", address2); |
| assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new |
| assertTrue("Address not found using stored procedure", (address2.getID() == address1.getID())); |
| |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery using a result-set mapping. |
| * 304400: Note: this test does not actually test a ResultSet return - it uses output parameters. |
| * To enable ResultSet testing - set returnsResultSet=true via orm.xml, annotation or via program call like the the core tests. |
| */ |
| public void testNamedStoredProcedureQueryWithResultSetFieldMapping() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263: we do not need to clear the cache for non-entity returns |
| Object[] values = (Object[]) em.createNamedQuery("SProcAddressWithResultSetFieldMapping").setParameter("address_id_v", address1.getID()).getSingleResult(); |
| assertTrue("Address data not found or returned using stored procedure", ((values!=null) && (values.length==6)) ); |
| assertNotNull("No results returned from store procedure call", values[1]); |
| assertTrue("Address not found using stored procedure", address1.getStreet().equals(values[1])); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery. |
| */ |
| public void testNamedStoredProcedureQueryInOut() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later |
| em.clear(); |
| |
| Query aQuery = em.createNamedQuery("SProcInOut").setParameter("ADDRESS_ID", address1.getID()); |
| Address address2 = (Address) aQuery.getSingleResult(); |
| |
| assertNotNull("Address returned from stored procedure is null", address2); |
| assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new |
| assertTrue("Address not found using stored procedure", address1.getID() == address2.getID()); |
| assertTrue("Address.street data returned doesn't match persisted address.street", address1.getStreet().equalsIgnoreCase(address2.getStreet())); |
| |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery that returns raw data |
| * bug 254946 |
| */ |
| public void testNamedStoredProcedureQueryWithRawData() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| |
| // 260263: we do not need to clear the cache for non-entity returns |
| Query aQuery = em.createNamedQuery("SProcInOutReturningRawData").setParameter("ADDRESS_ID", address1.getID()); |
| Object[] objectdata = (Object[])aQuery.getSingleResult(); |
| |
| assertTrue("Address data not found or returned using stored procedure", ((objectdata!=null)&& (objectdata.length==2)) ); |
| assertTrue("Address Id data returned doesn't match persisted address", (address1.getID() == (Long) objectdata[0]) ); |
| assertTrue("Address Street data returned doesn't match persisted address", ( address1.getStreet().equals(objectdata[1] )) ); |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| // Test for lazy OneToOne relation not getting triggered |
| public void testNonTriggerLazyForSProc() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| Employee employee2; |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Employee employee1 = new Employee(); |
| |
| employee1.setFirstName("Me"); |
| employee1.setId(11); |
| HugeProject hp = new HugeProject("big proj"); |
| |
| employee1.setHugeProject(hp); |
| em.persist(hp); |
| em.persist(employee1); |
| |
| commitTransaction(em); |
| em.clear(); |
| |
| beginTransaction(em); |
| |
| Query q = em.createNamedQuery("SProcEmployee"); |
| q.setParameter("EMP_ID", employee1.getId()); |
| q.setFlushMode(FlushModeType.COMMIT); |
| q.setHint(QueryHints.REFRESH, HintValues.TRUE); |
| q.setHint(QueryHints.REFRESH_CASCADE, CascadePolicy.CascadeByMapping); |
| employee2 = (Employee) q.getSingleResult(); |
| |
| ProviderUtil util = (new PersistenceProvider()).getProviderUtil(); |
| //status can be LoadState.NOT_LOADED or LoadState.UNKNOWN |
| assertFalse("ProviderUtil returned LOADED for isLoaded for hugeProject when it should not.", util.isLoadedWithReference(employee2, "hugeProject").equals(LoadState.LOADED)); |
| |
| } catch (RuntimeException e) { |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Tests an OptimisticLockingException is thrown when calling merge a detached and removed object. |
| * bug 272704 |
| */ |
| public void testOptimisticLockExceptionOnMerge() { |
| EntityManager em1 = createEntityManager(); |
| beginTransaction(em1); |
| |
| RuntimeException caughtException = null; |
| try { |
| Employee emp = new Employee(); |
| emp.setLastName("OptimisticLockExceptionOnMerge"); |
| emp.setVersion(10); |
| em1.persist(emp); |
| commitTransaction(em1); |
| closeEntityManager(em1); |
| |
| em1 = createEntityManager(); |
| beginTransaction(em1); |
| |
| emp = em1.find(Employee.class, emp.getId()); |
| em1.remove(emp); |
| commitTransaction(em1); |
| closeEntityManager(em1); |
| |
| em1 = createEntityManager(); |
| beginTransaction(em1); |
| //this is expected to throw an OptimisticLockException, because the version is >1 |
| em1.merge(emp); |
| |
| commitTransaction(em1); |
| |
| } catch (RuntimeException e) { |
| caughtException = e; |
| if (isTransactionActive(em1)){ |
| rollbackTransaction(em1); |
| } |
| } |
| closeEntityManager(em1); |
| if (caughtException == null) { |
| fail("Optimistic lock exception was not thrown."); |
| } else if (!(caughtException instanceof jakarta.persistence.OptimisticLockException)) { |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw caughtException; |
| } |
| } |
| |
| /** |
| * Tests an OptimisticLockingException is thrown when calling merge a detached and removed object. |
| * bug 272704 |
| */ |
| public void testOptimisticLockExceptionOnMergeWithAssumeExists() { |
| org.eclipse.persistence.sessions.Project project = getServerSession().getProject(); |
| ClassDescriptor descriptor = project.getDescriptor(Employee.class); |
| int existencePolicy = descriptor.getQueryManager().getDoesExistQuery().getExistencePolicy(); |
| |
| descriptor.getQueryManager().assumeExistenceForDoesExist(); |
| |
| try { |
| testOptimisticLockExceptionOnMerge(); |
| } finally { |
| descriptor.getQueryManager().getDoesExistQuery().setExistencePolicy(existencePolicy); |
| } |
| } |
| |
| /** |
| * Tests a @NamedStoredProcedureQuery that returns raw data using executeUpdate(). |
| */ |
| public void testModifyNamedStoredProcedureQueryWithRawData() { |
| if (!supportsStoredProcedures()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Address address1 = new Address(); |
| |
| address1.setCity("Ottawa"); |
| address1.setPostalCode("K1G6P3"); |
| address1.setProvince("ON"); |
| address1.setStreet("123 Street"); |
| address1.setCountry("Canada"); |
| |
| em.persist(address1); |
| commitTransaction(em); |
| beginTransaction(em); |
| |
| em.createNamedQuery("SProcInOutReturningRawData").setParameter("ADDRESS_ID", address1.getID()).getSingleResult(); |
| } catch (RuntimeException exception) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw exception; |
| } |
| commitTransaction(em); |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests a @PrivateOwned @OneToMany mapping. |
| */ |
| public void testRemoveDepartmentWithPrivateOwnedEquipment() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Department department = em.find(Department.class, deptId); |
| |
| if (department == null) { |
| fail("Department with id="+deptId+", was not found."); |
| } else { |
| Collection<Equipment> equipment = department.getEquipment().values(); |
| |
| if (equipment.isEmpty()){ |
| fail("Department with id="+deptId+", did not have any equipment."); |
| } else { |
| em.remove(department); |
| commitTransaction(em); |
| |
| assertNull("Department itself was not removed.", em.find(Department.class, deptId)); |
| |
| for (Equipment e : equipment) { |
| assertNull("New equipment was not deleted.", em.find(Equipment.class, e.getId())); |
| } |
| } |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| public void testRelationshipReadDuringClone(){ |
| EntityManager em = createEntityManager(); |
| AbstractSession session = getServerSession(); |
| ClassDescriptor departmentDesc = session.getDescriptor(Department.class); |
| DescriptorEventAdapter listener = new DescriptorEventAdapter(){ |
| @Override |
| public void postClone(DescriptorEvent event) { |
| ((Department)event.getObject()).getEquipment().size(); |
| } |
| }; |
| departmentDesc.getDescriptorEventManager().addListener(listener); |
| em.createQuery("SELECT e from Equipment e where e.department is not null").getResultList(); |
| departmentDesc.getDescriptorEventManager().removeListener(listener); |
| departmentDesc.getDescriptorEventManager().initialize(session); |
| closeEntityManager(em); |
| } |
| |
| /** |
| * Tests trying to update a read only class. |
| */ |
| public void testUpdateReadOnlyEquipmentCode() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Query query = em.createNamedQuery("findSQLEquipmentCodeA"); |
| EquipmentCode equipmentCode = (EquipmentCode) query.getSingleResult(); |
| |
| equipmentCode.setCode("Z"); |
| commitTransaction(em); |
| |
| // Nothing should have been written to the database. Query for |
| // EquipmentCode A again. If an exception is caught, then it was |
| // not found, therefore, updated on the db. |
| try { |
| query = em.createNamedQuery("findSQLEquipmentCodeA"); |
| query.getSingleResult(); |
| } catch (Exception e) { |
| fail("The read only EquipmentA was modified"); |
| } |
| } catch (RuntimeException e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| // Re-throw exception to ensure stacktrace appears in test result. |
| throw e; |
| } |
| |
| closeEntityManager(em); |
| } |
| |
| public void testMethodBasedTransformationMapping() { |
| internalTestTransformationMapping("normalHours"); |
| } |
| |
| public void testClassBasedTransformationMapping() { |
| internalTestTransformationMapping("overtimeHours"); |
| } |
| |
| //Bug#391251 : Test for @Column outside WriteTransformer annotation |
| public void testTransformationMappingWithColumnAnnotation() { |
| Door door = new Door(); |
| door.setId(100); |
| door.setHeight(8); |
| door.setWidth(5); |
| door.setRoom(null); |
| int year = 2013; |
| int month = 1; |
| int day = 30; |
| door.setSaleDate(Helper.dateFromYearMonthDate(year, month - 1, day)); |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| em.persist(door); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| int id = door.getId(); |
| String errorMsg = ""; |
| try { |
| this.clearCache(); |
| em = createEntityManager(); |
| door = em.find(Door.class, 100); |
| Calendar calendarSaleDate = Calendar.getInstance(); |
| calendarSaleDate.setTime(door.getSaleDate()); |
| if(calendarSaleDate.get(Calendar.YEAR) != year || calendarSaleDate.get(Calendar.MONTH) != (month - 1) || calendarSaleDate.get(Calendar.DAY_OF_MONTH) != day) { |
| errorMsg = "saleDate = " + door.getSaleDate().toString() + " is wrong"; |
| } |
| } catch (RuntimeException ex) { |
| fail("Failed to fetch data for testTransformationMappingWithColumnAnnotation" + ex.getMessage()); |
| } |
| |
| // clean up |
| beginTransaction(em); |
| try { |
| door = em.find(Door.class, door.getId()); |
| em.remove(door); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| if (errorMsg.length() != 0 ) { |
| fail(errorMsg); |
| } |
| } |
| |
| protected void internalTestTransformationMapping(String attributeName) { |
| // setup: create an Employee, insert into db |
| int startHour = 8, startMin = 30, startSec = 15; |
| int endHour = 17, endMin = 15, endSec = 45; |
| String firstName = attributeName; |
| Employee employee = new Employee(); |
| employee.setFirstName(firstName); |
| if(attributeName.equals("normalHours")) { |
| employee.setStartTime(Helper.timeFromHourMinuteSecond(startHour, startMin, startSec)); |
| employee.setEndTime(Helper.timeFromHourMinuteSecond(endHour, endMin, endSec)); |
| } else if(attributeName.equals("overtimeHours")) { |
| employee.setStartOvertime(Helper.timeFromHourMinuteSecond(startHour, startMin, startSec)); |
| employee.setEndOvertime(Helper.timeFromHourMinuteSecond(endHour, endMin, endSec)); |
| } else { |
| throw new RuntimeException("Unknown attributeName"); |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| em.persist(employee); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| int id = employee.getId(); |
| |
| // test |
| // clear cache |
| this.clearCache(); |
| // read the employee from the db |
| em = createEntityManager(); |
| employee = em.find(Employee.class,id); |
| |
| // verify |
| Calendar calendarStart = Calendar.getInstance(); |
| Calendar calendarEnd = Calendar.getInstance(); |
| if(attributeName.equals("normalHours")) { |
| calendarStart.setTime(employee.getStartTime()); |
| calendarEnd.setTime(employee.getEndTime()); |
| } else if(attributeName.equals("overtimeHours")) { |
| calendarStart.setTime(employee.getStartOvertime()); |
| calendarEnd.setTime(employee.getEndOvertime()); |
| } |
| String errorMsg = ""; |
| if(calendarStart.get(Calendar.HOUR_OF_DAY) != startHour || calendarStart.get(Calendar.MINUTE) != startMin || calendarStart.get(Calendar.SECOND) != startSec) { |
| if(attributeName.equals("normalHours")) { |
| errorMsg = "startTime = " + employee.getStartTime().toString() + " is wrong"; |
| } else if(attributeName.equals("overtimeHours")) { |
| errorMsg = "startOvertime = " + employee.getStartOvertime().toString() + " is wrong"; |
| } |
| } |
| if(calendarEnd.get(Calendar.HOUR_OF_DAY) != endHour || calendarEnd.get(Calendar.MINUTE) != endMin || calendarEnd.get(Calendar.SECOND) != endSec) { |
| if(errorMsg.length() > 0) { |
| errorMsg = errorMsg + "; "; |
| } |
| if(attributeName.equals("normalHours")) { |
| errorMsg = "endTime = " + employee.getEndTime().toString() + " is wrong"; |
| } else if(attributeName.equals("overtimeHours")) { |
| errorMsg = "endOvertime = " + employee.getEndOvertime().toString() + " is wrong"; |
| } |
| } |
| |
| // clean up |
| beginTransaction(em); |
| try { |
| employee = em.find(Employee.class, employee.getId()); |
| em.remove(employee); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| // test case for Bug25872190 ElBug538183 |
| public void testCursoredNativeQueryDefinedViaAnnotation() { |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Query q = em.createNamedQuery("allTestEntitiesAnnotated"); |
| q.setHint(QueryHints.CURSOR, true); |
| try { |
| CursoredStream stream = (CursoredStream) q.getSingleResult(); |
| assertTrue(stream.hasNext()); |
| } catch (QueryException qe) { |
| fail("Cursored Native Query via Annotation threw QueryException"); |
| } |
| commitTransaction(em); |
| }finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| |
| public void testCursorStream() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Room room1 = new Room(); |
| Door east = new Door(); |
| try { |
| //Setup Rooms and Doors |
| room1.setId(10001); |
| east.setId(100); |
| east.setHeight(8); |
| east.setWidth(5); |
| int year = 2013; |
| int month = 1; |
| int day = 30; |
| east.setSaleDate(Helper.dateFromYearMonthDate(year, month - 1, day)); |
| east.setRoom(room1); |
| room1.addDoor(east); |
| |
| try { |
| em.persist(room1); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| em = createEntityManager(); |
| |
| Query resultsXferQuery = em.createQuery("SELECT r, d " |
| + "FROM Room r " |
| + "JOIN FETCH r.doors " |
| + "LEFT JOIN Door d " |
| + "WHERE d MEMBER OF r.doors" |
| ); |
| |
| resultsXferQuery.setHint(QueryHints.CURSOR, true); |
| |
| try { |
| CursoredStream stream = (CursoredStream)resultsXferQuery.getSingleResult(); |
| while (!stream.atEnd()) { |
| stream.read(); |
| } |
| stream.clear(); |
| stream.close(); |
| } catch (NullPointerException npe) { |
| fail("CursoredStream with join threw an NPE"); |
| } |
| // clean up |
| beginTransaction(em); |
| room1 = em.find(Room.class, room1.getId()); |
| em.remove(room1); |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| /** |
| * Tests Property and Properties annotations |
| */ |
| public void testProperty() { |
| EntityManager em = createEntityManager(); |
| ClassDescriptor descriptor = getServerSession().getDescriptorForAlias("Employee"); |
| ClassDescriptor aggregateDescriptor = getServerSession().getDescriptor(EmploymentPeriod.class); |
| |
| closeEntityManager(em); |
| |
| String errorMsg = ""; |
| |
| if (descriptor == null) { |
| errorMsg += " Descriptor for Employee alias was not found;"; |
| } |
| if (aggregateDescriptor == null) { |
| errorMsg += " Descriptor for EmploymentPeriod.class was not found;"; |
| } |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| |
| // verify properties set on Employee instance |
| errorMsg += verifyPropertyValue(descriptor, "entityName", String.class, "Employee"); |
| errorMsg += verifyPropertyValue(descriptor, "entityIntegerProperty", Integer.class, 1); |
| |
| // each attribute of Employee was assigned a property attributeName with the value attribute name. |
| for(DatabaseMapping mapping : descriptor.getMappings()) { |
| errorMsg += verifyPropertyValue(mapping, "attributeName", String.class, mapping.getAttributeName()); |
| } |
| |
| // attribute m_lastName has many properties of different types |
| DatabaseMapping mapping = descriptor.getMappingForAttributeName("lastName"); |
| errorMsg += verifyPropertyValue(mapping, "BooleanProperty", Boolean.class, Boolean.TRUE); |
| errorMsg += verifyPropertyValue(mapping, "ByteProperty", Byte.class, (byte) 1); |
| errorMsg += verifyPropertyValue(mapping, "CharacterProperty", Character.class, 'A'); |
| errorMsg += verifyPropertyValue(mapping, "DoubleProperty", Double.class, 1.0); |
| errorMsg += verifyPropertyValue(mapping, "FloatProperty", Float.class, 1F); |
| errorMsg += verifyPropertyValue(mapping, "IntegerProperty", Integer.class, 1); |
| errorMsg += verifyPropertyValue(mapping, "LongProperty", Long.class, 1L); |
| errorMsg += verifyPropertyValue(mapping, "ShortProperty", Short.class, (short) 1); |
| errorMsg += verifyPropertyValue(mapping, "BigDecimalProperty", java.math.BigDecimal.class, java.math.BigDecimal.ONE); |
| errorMsg += verifyPropertyValue(mapping, "BigIntegerProperty", java.math.BigInteger.class, java.math.BigInteger.ONE); |
| errorMsg += verifyPropertyValue(mapping, "byte[]Property", byte[].class, new byte[]{1, 2, 3, 4}); |
| errorMsg += verifyPropertyValue(mapping, "char[]Property", char[].class, new char[]{'a', 'b', 'c'}); |
| errorMsg += verifyPropertyValue(mapping, "Byte[]Property", Byte[].class, new byte[]{1, 2, 3, 4}); |
| errorMsg += verifyPropertyValue(mapping, "Character[]Property", Character[].class, new char[]{'a', 'b', 'c'}); |
| errorMsg += verifyPropertyValue(mapping, "TimeProperty", java.sql.Time.class, Helper.timeFromString("13:59:59")); |
| errorMsg += verifyPropertyValue(mapping, "TimeStampProperty", java.sql.Timestamp.class, Helper.timestampFromString("2008-04-10 13:59:59")); |
| errorMsg += verifyPropertyValue(mapping, "DateProperty", java.sql.Date.class, Helper.dateFromString("2008-04-10")); |
| |
| // verify property set on EmploymentPeriod embeddable |
| errorMsg += verifyPropertyValue(aggregateDescriptor, "embeddableClassName", String.class, "EmploymentPeriod"); |
| |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| protected String verifyPropertyValue(ClassDescriptor descriptor, String propertyName, Class<?> expectedPropertyValueType, Object expectedPropertyValue) { |
| return verifyPropertyValue(propertyName, descriptor.getProperty(propertyName), expectedPropertyValueType, expectedPropertyValue, Helper.getShortClassName(descriptor.getJavaClass()) + " descriptor"); |
| } |
| protected String verifyPropertyValue(DatabaseMapping mapping, String propertyName, Class<?> expectedPropertyValueType, Object expectedPropertyValue) { |
| return verifyPropertyValue(propertyName, mapping.getProperty(propertyName), expectedPropertyValueType, expectedPropertyValue, mapping.getAttributeName() + " attribute"); |
| } |
| protected String verifyPropertyValue(String propertyName, Object propertyValue, Class<?> expectedPropertyValueType, Object expectedPropertyValue, String masterName) { |
| String errorMsg = ""; |
| String errorPrefix = " property " + propertyName + " for " + masterName; |
| if(expectedPropertyValueType == null) { |
| if(propertyValue != null) { |
| errorMsg = errorPrefix + " value is " + propertyValue.toString() + " , was expected to be null."; |
| } |
| return errorMsg; |
| } |
| if(propertyValue == null) { |
| errorMsg = errorPrefix + " is missing;"; |
| } else if(!expectedPropertyValueType.isInstance(propertyValue)) { |
| errorMsg = errorPrefix + " is instance of " + propertyValue.getClass().getName() + ", " + expectedPropertyValueType.getName() + " was expected;"; |
| } else { |
| if(propertyValue.getClass().isArray()) { |
| if(Array.getLength(propertyValue) != Array.getLength(expectedPropertyValue)) { |
| errorMsg = errorPrefix + " has array value of size " + Array.getLength(propertyValue) + ", " + Array.getLength(expectedPropertyValue) + " was expected;"; |
| } else { |
| for(int i=0; i < Array.getLength(propertyValue); i++) { |
| if(!Array.get(propertyValue, i).equals(Array.get(expectedPropertyValue, i))) { |
| errorMsg = errorPrefix + " has array with "+i+"th element value " + Array.get(propertyValue, i).toString() + ", " + Array.get(expectedPropertyValue, i).toString() + " was expected;"; |
| } |
| } |
| } |
| } else if (!propertyValue.equals(expectedPropertyValue)) { |
| errorMsg = errorPrefix + " has value " + propertyValue.toString() + ", " + expectedPropertyValue.toString() + " was expected;"; |
| } |
| } |
| return errorMsg; |
| } |
| |
| public void testUnidirectionalPersist() { |
| String lastName = "testUnidirectionalPersist"; |
| |
| // persist employees |
| List<Employee> employeesPersisted = persistEmployeesWithUnidirectionalMappings(lastName); |
| |
| // clear cache |
| clearCache(); |
| |
| // read the persisted employees back |
| EntityManager em = createEntityManager(); |
| List<Employee> employeesRead = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.lastName = '"+lastName+"'").getResultList(); |
| closeEntityManager(em); |
| |
| // verify number persisted and read is the same |
| if(employeesPersisted.size() != employeesRead.size()) { |
| //clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| fail("Persisted " + employeesPersisted.size() + " employees, but read back " + employeesRead.size()); |
| } |
| |
| // verify that the persisted and read objects are equal |
| ServerSession session = JUnitTestCase.getServerSession(); |
| String errorMsg = ""; |
| for(int i=0; i<employeesPersisted.size(); i++) { |
| for(int j=0; j<employeesRead.size(); j++) { |
| if(employeesPersisted.get(i).getFirstName().equals(employeesRead.get(j).getFirstName())) { |
| if(!session.compareObjects(employeesPersisted.get(i), employeesRead.get(j))) { |
| errorMsg += "Employee " + employeesPersisted.get(i).getFirstName() +" was not persisted correctly."; |
| } |
| } |
| } |
| } |
| |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| |
| // non-empty error message means the test has failed |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| public void testUnidirectionalUpdate() { |
| String lastName = "testUnidirectionalUpdate"; |
| |
| // em used for both persist and update |
| EntityManager em = createEntityManager(); |
| // persist employees |
| List<Employee> employeesPersisted = persistEmployeesWithUnidirectionalMappings(lastName, em); |
| // update persisted employees: |
| beginTransaction(em); |
| try { |
| // add a new dealer to the first employee |
| employeesPersisted.get(0).addDealer(new Dealer("New", lastName)); |
| // remove a dealer from the second employee |
| employeesPersisted.get(1).getDealers().remove(1); |
| // move a dealer from the first to the second employee |
| employeesPersisted.get(1).addDealer(employeesPersisted.get(0).getDealers().remove(0)); |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| // clear cache |
| clearCache(); |
| |
| em = createEntityManager(); |
| // read the updated employees back |
| List<Employee> employeesRead = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.lastName = '"+lastName+"'").getResultList(); |
| |
| // verify number persisted and read is the same |
| if(employeesPersisted.size() != employeesRead.size()) { |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| fail("Updated " + employeesPersisted.size() + " employees, but read back " + employeesRead.size()); |
| } |
| |
| // verify that the persisted and read objects are equal |
| ServerSession session = JUnitTestCase.getServerSession(); |
| beginTransaction(em); |
| String errorMsg = ""; |
| try{ |
| for(int i=0; i<employeesPersisted.size(); i++) { |
| for(int j=0; j<employeesRead.size(); j++) { |
| if (isOnServer()) { |
| Employee emp1 = em.find(Employee.class, employeesPersisted.get(i).getId()); |
| Employee emp2 = em.find(Employee.class, employeesRead.get(j).getId()); |
| if(emp1.getFirstName().equals(emp2.getFirstName())) { |
| if(!session.compareObjects(emp1, emp2)) { |
| errorMsg += "Employee " + emp1.getFirstName() +" was not updated correctly."; |
| } |
| } |
| } else { |
| if(employeesPersisted.get(i).getFirstName().equals(employeesRead.get(j).getFirstName())) { |
| if(!session.compareObjects(employeesPersisted.get(i), employeesRead.get(j))) { |
| errorMsg += "Employee " + employeesPersisted.get(i).getFirstName() +" was not updated correctly."; |
| } |
| } |
| } |
| } |
| } |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| |
| // non-empty error message means the test has failed |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| public void testUnidirectionalFetchJoin() { |
| String lastName = "testUnidirectionalFetchJoin"; |
| |
| // persist employees |
| persistEmployeesWithUnidirectionalMappings(lastName); |
| |
| // clear cache |
| clearCache(); |
| |
| EntityManager em = createEntityManager(); |
| // read the persisted employees back - without fetch join |
| List<Employee> employeesRead = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.lastName = '"+lastName+"'").getResultList(); |
| closeEntityManager(em); |
| |
| // clear cache |
| clearCache(); |
| |
| // read the persisted employees back - with fetch join. |
| em = createEntityManager(); |
| List<Employee> employeesReadWithFetchJoin = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.dealers WHERE e.lastName = '"+lastName+"'").getResultList(); |
| closeEntityManager(em); |
| |
| // verify that the persisted and read employees are the same. |
| // The comparison cascades to all references and requires the same state of indirection: |
| // it fails in case an object has triggered indirection for particular attribute and compared object's indirection for this attribute is not triggered. |
| // The expected result of join fetch query is Employee.dealers being triggered - so need to trigger it on the control collection (getDealers.size() does that); |
| // also the expected result should have an object for each row returned - therefore number of inclusions of each Employee equals its dealers.size() |
| List<Employee> employeesControl = new ArrayList<Employee>(); |
| for(int i=0; i<employeesRead.size(); i++) { |
| int nDialers = employeesRead.get(i).getDealers().size(); |
| for(int j=0; j<nDialers; j++) { |
| employeesControl.add(employeesRead.get(i)); |
| } |
| } |
| ServerSession session = JUnitTestCase.getServerSession(); |
| String errorMsg = JoinedAttributeTestHelper.compareCollections(employeesControl, employeesReadWithFetchJoin, session.getClassDescriptor(Employee.class), session); |
| |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| |
| // non-empty error message means the test has failed |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| public void testUnidirectionalTargetLocking_AddRemoveTarget() { |
| String lastName = "testUnidirectionalTargetLocking_ART"; |
| |
| EntityManager em = createEntityManager(); |
| // persist employees |
| List<Employee> employeesPersisted = persistEmployeesWithUnidirectionalMappings(lastName, em); |
| |
| // remove a dealer from the second employee: |
| Dealer dealer; |
| beginTransaction(em); |
| try { |
| Employee emp1 = em.find(Employee.class, employeesPersisted.get(1).getId()); |
| dealer = emp1.getDealers().remove(1); |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| String errorMsg = ""; |
| |
| // verify the version both in the cache and in the db |
| int version2 = getVersion(em, dealer); |
| if(version2 != 2) { |
| errorMsg += "In the cache the removed dealer's version is " + version2 + " (2 was expected); "; |
| } |
| beginTransaction(em); |
| try { |
| Dealer dealer2 = em.find(Dealer.class, dealer.getId()); |
| em.refresh(dealer2); |
| version2 = getVersion(em, dealer2); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| } |
| if(version2 != 2) { |
| errorMsg += "In the db the removed dealer's version is " + version2 + " (2 was expected); "; |
| } |
| beginTransaction(em); |
| Dealer dealer3; |
| try { |
| Employee emp2 = em.find(Employee.class, employeesPersisted.get(1).getId()); |
| dealer3 = em.find(Dealer.class, dealer.getId()); |
| emp2.getDealers().add(dealer3); |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| // verify the version both in the cache and in the db |
| int version3 = getVersion(em, dealer3); |
| if(version3 != 3) { |
| errorMsg += "In the cache the added dealer's version is " + version3 + " (3 was expected); "; |
| } |
| |
| beginTransaction(em); |
| try { |
| Dealer dealer4 = em.find(Dealer.class, dealer3.getId()); |
| em.refresh(dealer4); |
| version3 = getVersion(em, dealer4); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| } |
| if(version3 != 3) { |
| errorMsg += "In the db the added dealer's version is " + version3 + " (3 was expected)"; |
| } |
| |
| closeEntityManager(em); |
| |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| |
| // non-empty error message means the test has failed |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| public void testUnidirectionalTargetLocking_DeleteSource() { |
| String lastName = "testUnidirectionalTargetLocking_DS"; |
| |
| // persist employees (there should be two of them) |
| List<Employee> persistedEmployees = persistEmployeesWithUnidirectionalMappings(lastName); |
| // cache their dealers' ids |
| ArrayList<Integer> dealersIds = new ArrayList<Integer>(); |
| for(int i=0; i<persistedEmployees.size(); i++) { |
| Employee emp = persistedEmployees.get(i); |
| for(int j=0; j<emp.getDealers().size(); j++) { |
| dealersIds.add(emp.getDealers().get(j).getId()); |
| } |
| } |
| |
| // clear cache |
| clearCache(); |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| // read the persisted employees |
| List<Employee> readEmployees = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.lastName = '"+lastName+"'").getResultList(); |
| |
| // trigger indirection on the second employee's dealers |
| readEmployees.get(1).getDealers().size(); |
| |
| // delete the Employees (there should be two of them). |
| try { |
| for(Employee emp: readEmployees) { |
| em.remove(emp); |
| } |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| // find employees' dealers and verify their versions - all should be 2. |
| beginTransaction(em); |
| String errorMsg = ""; |
| try{ |
| for(int i=0; i<dealersIds.size(); i++) { |
| Dealer dealer = em.find(Dealer.class, dealersIds.get(i)); |
| |
| // verify the version both in the cache and in the db |
| int version2 = getVersion(em, dealer); |
| if(version2 != 2) { |
| errorMsg += "In the cache dealer "+dealer.getFirstName()+"'s version is " + version2 + " (2 was expected); "; |
| } |
| em.refresh(dealer); |
| |
| version2 = getVersion(em, dealer); |
| if(version2 != 2) { |
| errorMsg += "In the db dealer "+dealer.getFirstName()+"'s version is " + version2 + " (2 was expected); "; |
| } |
| } |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| } |
| |
| closeEntityManager(em); |
| |
| // clean-up |
| deleteEmployeesWithUnidirectionalMappings(lastName); |
| |
| // non-empty error message means the test has failed |
| if(errorMsg.length() > 0) { |
| fail(errorMsg); |
| } |
| } |
| |
| /** |
| * Fix for bug 247078: eclipselink-orm.xml schema should allow lob and |
| * enumerated on version and id mappings |
| */ |
| public void testEnumeratedPrimaryKeys(){ |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| |
| ViolationCode codeA = new ViolationCode(); |
| codeA.setId(ViolationCodeId.A); |
| codeA.setDescription("Violation A"); |
| em.persist(codeA); |
| |
| ViolationCode codeB = new ViolationCode(); |
| codeB.setId(ViolationCodeId.B); |
| codeB.setDescription("Violation B"); |
| em.persist(codeB); |
| |
| ViolationCode codeC = new ViolationCode(); |
| codeC.setId(ViolationCodeId.C); |
| codeC.setDescription("Violation C"); |
| em.persist(codeC); |
| |
| ViolationCode codeD = new ViolationCode(); |
| codeD.setId(ViolationCodeId.D); |
| codeD.setDescription("Violation D"); |
| em.persist(codeD); |
| |
| Violation violation = new Violation(); |
| violation.setId(ViolationID.V1); |
| violation.getViolationCodes().add(codeA); |
| violation.getViolationCodes().add(codeC); |
| violation.getViolationCodes().add(codeD); |
| em.persist(violation); |
| |
| commitTransaction(em); |
| |
| // Force the read to hit the database and make sure the violation is read back. |
| clearCache(); |
| em.clear(); |
| Violation refreshedViolation = em.find(Violation.class, violation.getId()); |
| assertNotNull("Unable to read back the violation", refreshedViolation); |
| assertTrue("Violation object did not match after refresh", getServerSession().compareObjects(violation, refreshedViolation)); |
| } catch (Exception e) { |
| fail("An error occurred: " + e.getMessage()); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 400022 |
| * Test batch fetch with join fetch with batching on a M:M |
| */ |
| public void testProjectToEmployeeWithBatchFetchJoinFetch() { |
| clearCache(); |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| // Count SQL. |
| QuerySQLTracker counter = new QuerySQLTracker(getServerSession()); |
| try { |
| Query query = em.createQuery("SELECT p FROM Project p", Project.class); |
| query.setHint(QueryHints.BATCH, "p.teamMembers"); |
| query.setHint(QueryHints.BATCH, "p.teamMembers.projects"); |
| query.setHint(QueryHints.BATCH, "p.teamMembers.phoneNumbers.owner"); |
| query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN); |
| query.setHint(QueryHints.FETCH, "p.teamMembers.address"); |
| query.setHint(QueryHints.FETCH, "p.teamMembers.phoneNumbers"); |
| |
| List<Project> results = query.getResultList(); |
| |
| // XXX - size here may vary depending on the model |
| if (isWeavingEnabled() && counter.getSqlStatements().size() > 9) { |
| fail("Should have been 9 queries but was: " + counter.getSqlStatements().size()); |
| } |
| |
| for (Project project : results) { |
| assertNotNull("Project cannot be null", project); |
| Employee employee = project.getTeamLeader(); |
| if (employee != null) { |
| employee.getProjects().size(); |
| } |
| } |
| |
| if (isWeavingEnabled() && counter.getSqlStatements().size() > 18) { |
| fail("Should have been 18 queries but was: " + counter.getSqlStatements().size()); |
| } |
| } finally { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| if (counter != null) { |
| counter.remove(); |
| } |
| } |
| } |
| |
| /** |
| * Bug 400022 |
| * Test batch fetch with join fetch on a 1:M |
| */ |
| public void testEmployeeToPhoneNumberWithBatchFetchJoinFetch() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| |
| Employee emp1 = new Employee(); |
| emp1.setMale(); |
| emp1.setFirstName("Mickey"); |
| emp1.setLastName("O'Neil"); |
| |
| Employee emp2 = new Employee(); |
| emp2.setMale(); |
| emp2.setFirstName("Tony"); |
| emp2.setLastName("Bullet Tooth"); |
| |
| em.persist(emp1); |
| em.persist(emp2); |
| |
| em.flush(); |
| |
| Query query = em.createQuery("SELECT e FROM Employee e", Employee.class); |
| query.setHint(QueryHints.BATCH, "e.projects"); |
| query.setHint(QueryHints.BATCH, "e.projects.teamMembers"); |
| query.setHint(QueryHints.BATCH, "e.phoneNumbers.owner"); |
| query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN); |
| query.setHint(QueryHints.FETCH, "e.address"); |
| query.setHint(QueryHints.FETCH, "e.phoneNumbers"); |
| |
| List<Employee> results = query.getResultList(); |
| for (Employee employee : results) { |
| assertNotNull("Employee cannot be null", employee); |
| Collection<PhoneNumber> phoneNumbers = employee.getPhoneNumbers(); |
| for (PhoneNumber phoneNumber : phoneNumbers) { |
| assertNotNull("PhoneNumber cannot be null", phoneNumber); |
| } |
| } |
| } finally { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 400022 |
| * Test batch fetch with join fetch on a 1:1 |
| */ |
| public void testEmployeeToAddressWithBatchFetchJoinFetch() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| |
| Employee emp1 = new Employee(); |
| emp1.setMale(); |
| emp1.setFirstName("Mickey"); |
| emp1.setLastName("O'Neil"); |
| |
| Employee emp2 = new Employee(); |
| emp2.setMale(); |
| emp2.setFirstName("Tony"); |
| emp2.setLastName("Bullet Tooth"); |
| |
| em.persist(emp1); |
| em.persist(emp2); |
| |
| em.flush(); |
| |
| Query query = em.createQuery("SELECT e FROM Employee e", Employee.class); |
| query.setHint(QueryHints.BATCH, "e.projects"); |
| query.setHint(QueryHints.BATCH, "e.projects.teamMembers"); |
| query.setHint(QueryHints.BATCH, "e.phoneNumbers.owner"); |
| query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN); |
| query.setHint(QueryHints.FETCH, "e.address"); |
| query.setHint(QueryHints.FETCH, "e.phoneNumbers"); |
| |
| List<Employee> results = query.getResultList(); |
| for (Employee employee : results) { |
| assertNotNull("Employee cannot be null", employee); |
| String addrString = String.valueOf(employee.getAddress()); |
| } |
| } finally { |
| rollbackTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 416003 |
| * Test batch fetch with join fetch on a 1:m |
| */ |
| public void testEmployeeFetchWithAlias() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| Query query = em.createQuery("SELECT d FROM Employee d join fetch d.phoneNumbers p", Employee.class); |
| |
| List<Employee> results = query.getResultList(); |
| assertTrue ("Test failed because extra join resulted in too many results", results.size() < 30); |
| }finally{ |
| closeEntityManager(em); |
| } |
| } |
| |
| |
| /** |
| * Bug 415082 - JoinFetch does not refresh cache even though REFRESH hint is set to true |
| * Test that a refresh is performed on a queried and related object, with fetchjoins |
| */ |
| public void testJoinFetchWithRefreshOnRelatedEntity() { |
| // create test entities |
| Employee emp = null; |
| Department dept = null; |
| EntityManager em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| emp = new Employee("Bob", "Robertson"); |
| dept = new Department("Pomology"); |
| emp.setDepartment(dept); |
| |
| em.persist(emp); |
| em.persist(dept); |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // update tables directly |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| Session session = ((JpaEntityManager)em.getDelegate()).getActiveSession(); |
| if(session.getDatasourcePlatform().isSQLServer()) { |
| session.executeNonSelectingSQL("UPDATE t0 SET t0.F_NAME='Joe', t0.L_NAME='Josephson' FROM CMP3_EMPLOYEE t0 WHERE t0.EMP_ID=" + emp.getId()); |
| session.executeNonSelectingSQL("UPDATE t1 SET t1.NAME='Xenobiology' FROM CMP3_DEPT t1 WHERE t1.ID=" + dept.getId()); |
| } |
| else { |
| session.executeNonSelectingSQL("UPDATE CMP3_EMPLOYEE t0 SET t0.F_NAME='Joe', t0.L_NAME='Josephson' WHERE t0.EMP_ID=" + emp.getId()); |
| session.executeNonSelectingSQL("UPDATE CMP3_DEPT t1 SET t1.NAME='Xenobiology' WHERE t1.ID=" + dept.getId()); |
| } |
| |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // perform refreshing query |
| em = createEntityManager(); |
| try { |
| Query query = em.createQuery("select e from Employee e where e.id = :pk"); |
| query.setParameter("pk", emp.getId()); |
| query.setHint(QueryHints.REFRESH, HintValues.TRUE); |
| Employee empReturned = (Employee)query.getSingleResult(); |
| |
| // validate refresh |
| assertNotNull("Employee should not be null", empReturned); |
| Department deptReturned = empReturned.getDepartment(); |
| assertNotNull("Department should not be null", deptReturned); |
| assertEquals("Employee should have the same id", emp.getId(), empReturned.getId()); |
| assertEquals("Department should have the same id", dept.getId(), deptReturned.getId()); |
| assertEquals("Employee's firstName should be refreshed", "Joe", empReturned.getFirstName()); |
| assertEquals("Employee's lastName should be refreshed", "Josephson", empReturned.getLastName()); |
| assertEquals("Department's name should be refreshed", "Xenobiology", deptReturned.getName()); |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // clean up |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| em.remove(em.find(Employee.class, emp.getId())); |
| em.remove(em.find(Department.class, dept.getId())); |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 464088 |
| * Test non-historized Entity eager-referencing a historized Entity's queries function correctly |
| * when read all queries are executed on a 'historical' session before a 'regular' session. |
| * Uses very specialized non-cacheable entities: Oyster bi-directional eager 1:1 to: Pearl(historized) |
| */ |
| public void testHistoryRelationshipQueryInitialization() { |
| // setup |
| EntityManager em = createEntityManager(); |
| |
| Oyster oyster = null; |
| Pearl pearl = null; |
| try { |
| beginTransaction(em); |
| |
| oyster = new Oyster(); |
| oyster.setColor("Black"); |
| pearl = new Pearl(); |
| pearl.setName("Bob"); |
| oyster.setPearl(pearl); |
| pearl.setOyster(oyster); |
| |
| em.persist(oyster); |
| em.flush(); |
| |
| try { |
| Thread.sleep(1000); // pause for a bit to allow timestamps to be different |
| } catch (InterruptedException ie) {} // ignore |
| |
| oyster.getPearl().setName("Doug"); // change related entity for history entry |
| |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // test |
| em = createEntityManager(); |
| try { |
| Calendar asOfDate = Calendar.getInstance(); |
| asOfDate.set(1999, 1, 1, 12, 0, 0); |
| |
| // execute a historical query against the non-historical Oyster entity |
| Session client = JpaHelper.getServerSession(em.getEntityManagerFactory()).acquireClientSession(); |
| Session historical = client.acquireHistoricalSession(new AsOfClause(asOfDate)); |
| |
| List<Oyster> oysters = (List<Oyster>)historical.readAllObjects(Oyster.class); |
| assertTrue("Historical query: Oysters should be non-empty", oysters.size() > 0); |
| for (Oyster oysterElem : oysters) { |
| assertNull("Historical query: Oyster should not have a pearl", oysterElem.getPearl()); |
| } |
| |
| // execute a non historical query through JPQL against the Oyster entity |
| oysters = em.createQuery("SELECT e FROM Oyster e", Oyster.class).getResultList(); |
| assertTrue("JPA query: Oysters should be non-empty", oysters.size() > 0); |
| for (Oyster oysterElem : oysters) { |
| assertNotNull("JPA query: Oyster should have a pearl, historical query executed", oysterElem.getPearl()); |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // reset |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| oyster = em.find(Oyster.class, oyster.getId()); |
| if (oyster != null) { |
| em.remove(oyster); |
| } |
| pearl = em.find(Pearl.class, pearl.getId()); |
| if (pearl != null) { |
| em.remove(pearl); |
| } |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 470007 - NPE in normalize() when querying on ElementCollection-{@literal >}CollectionTable, with query results caching enabled |
| * Tests querying across an Entity (ToDoList) containing an ElementCollection with a CollectionTable, referencing a |
| * basic type (String). A NullPointerException was previously observed when query results caching is enabled on the query. |
| */ |
| public void testQueryJoinBasicCollectionTableUsingQueryResultsCache() { |
| // setup |
| EntityManager em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| String commonName = "My List"; |
| String commonItem = "Feed the cat"; |
| |
| // setup |
| // ToDoList has a Set<String>, mapped to an @ElementCollection, using @CollectionTable (String) |
| ToDoList bobsList = new ToDoList(1, commonName); |
| bobsList.addItem(commonItem); |
| bobsList.addItem("Cook dinner"); |
| bobsList.addItem("Watch TV"); |
| |
| ToDoList jensList = new ToDoList(2, commonName); |
| jensList.addItem("Feed the dog"); |
| jensList.addItem("Hire and fire"); |
| jensList.addItem("Eat chocolate"); |
| |
| ToDoList bertsList = new ToDoList(3, commonName); |
| bertsList.addItem(commonItem); |
| bertsList.addItem("Feed the kids"); |
| bertsList.addItem("Feed the wife"); |
| |
| em.persist(bobsList); |
| em.persist(jensList); |
| em.persist(bertsList); |
| em.flush(); |
| |
| // test |
| Query query = em.createQuery("SELECT tdl FROM ToDoList tdl JOIN tdl.items items " + |
| "WHERE tdl.name = :p_name AND items = :p_itemName"); |
| query.setHint(QueryHints.QUERY_RESULTS_CACHE, HintValues.TRUE); |
| |
| query.setParameter("p_name", commonName); |
| query.setParameter("p_itemName", commonItem); |
| List<ToDoList> listsReturned = query.getResultList(); |
| |
| // verify |
| assertNotNull("Query results should not be null", listsReturned); |
| assertSame("Query results size", 2, listsReturned.size()); // 2 results expected |
| |
| for (ToDoList aList : listsReturned) { |
| assertEquals(commonName, aList.getName()); |
| assertTrue(aList.getItems().contains(commonItem)); |
| } |
| |
| } finally { |
| // reset - rollback |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 470161 - ServerSession links RepeatableWriteUnitOfWork via entity / IndirectList / QueryBasedValueHolder\ |
| * |
| * Through the UoW: Persist a new object, read an existing object in (building from rows, original not put in the |
| * shared cache), associate existing object with new object, commit. Previously, after the changes are merged |
| * into the shared cache, the transparent collection on the existing object has a wrapped VH from the initial uow |
| * query, which internally references the uow session, not the shared session. |
| */ |
| public void testTransparentIndirectionValueHolderSessionReset() { |
| Employee emp = null; |
| Dealer dealer = null; |
| |
| // setup |
| EntityManager em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| dealer = new Dealer(); |
| dealer.setFirstName("Angle"); |
| dealer.setLastName("Bracket"); |
| em.persist(dealer); |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| clearCache(); // start test with an empty cache |
| } |
| |
| // test |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| emp = new Employee(); |
| emp.setFemale(); |
| emp.setFirstName("Case"); |
| emp.setLastName("Statement"); |
| em.persist(emp); |
| |
| Query query = em.createQuery("select d from Dealer d where d.firstName = :firstName and d.lastName = :lastName"); |
| query.setParameter("firstName", dealer.getFirstName()); |
| query.setParameter("lastName", dealer.getLastName()); |
| List<Dealer> resultsList = query.getResultList(); |
| assertTrue("List returned should be non-empty", resultsList.size() > 0); |
| |
| Dealer dealerFound = resultsList.get(0); |
| emp.addDealer(dealerFound); |
| |
| commitTransaction(em); |
| |
| // verify valueholder configuration in shared cache |
| Session parentSession = JpaHelper.getServerSession(em.getEntityManagerFactory()); |
| Dealer cachedDealer = (Dealer) parentSession.getIdentityMapAccessor().getFromIdentityMap(dealer); |
| assertNotNull("Dealer with id should be in the cache: " + dealer.getId(), cachedDealer); |
| |
| ClassDescriptor descriptor = parentSession.getDescriptor(Dealer.class); |
| DatabaseMapping mapping = descriptor.getMappingForAttributeName("customers"); |
| IndirectCollection indirectCollection = (IndirectCollection) mapping.getAttributeValueFromObject(cachedDealer); |
| assertFalse("Collection VH should be uninstantiated", indirectCollection.isInstantiated()); |
| |
| DatabaseValueHolder dbValueHolder = (DatabaseValueHolder) indirectCollection.getValueHolder(); |
| assertFalse("Referenced VH should be uninstantiated", dbValueHolder.isInstantiated()); |
| |
| Session vhSession = dbValueHolder.getSession(); |
| assertSame("Dealer.customers VH session should reference the shared session", parentSession, vhSession); |
| } finally { |
| closeEntityManager(em); |
| } |
| |
| // reset |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| emp = em.find(Employee.class, emp.getId()); |
| if (emp != null) { |
| em.remove(emp); |
| } |
| dealer = em.find(Dealer.class, dealer.getId()); |
| if (dealer != null) { |
| em.remove(dealer); |
| } |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 489898 - RepeatableWriteUnitOfWork linked by QueryBasedValueHolder in shared cache in specific scenario |
| * |
| * Complex scenario: In a transaction, associate an existing object to a new object, refresh the existing object. |
| * In a second transaction, read the new object and traverse relationships to the existing object, and trigger |
| * an indirect relationship. The existing wrapped indirection query on the indirect relationship should |
| * ensure that the UnitOfWork (RepeatableWriteUnitOfWork) used for the query is unreferenced correctly, to |
| * avoid referencing it within the shared cache, via the existing referenced query. |
| */ |
| public void testTransparentIndirectionQuerySessionReset() { |
| Bill bill = null; |
| BillLine billLine = null; |
| BillLineItem billLineItem = null; |
| BillAction billAction = null; |
| |
| // setup |
| EntityManager em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| bill = new Bill(); |
| bill.setOrderIdentifier("Test Bill"); |
| |
| billLine = new BillLine(); |
| billLine.setQuantity(6); |
| bill.addBillLine(billLine); |
| |
| billLineItem = new BillLineItem(); |
| billLineItem.setItemName("Test Widget"); |
| billLine.addBillLineItem(billLineItem); |
| |
| em.persist(bill); |
| em.persist(billLine); |
| em.persist(billLineItem); |
| |
| commitTransaction(em); |
| |
| assertNotNull("bill should be non-null", bill); |
| assertNotNull("bill's id should be non-null", bill.getId()); |
| assertNotNull("billLine should be non-null", billLine); |
| assertNotNull("billLine's id should be non-null", billLine.getId()); |
| assertNotNull("billLineItem should be non-null", billLineItem); |
| assertNotNull("billLineItem's id should be non-null", billLineItem.getId()); |
| } finally { |
| closeEntityManager(em); |
| clearCache(); // start test with an empty cache |
| } |
| |
| try { |
| // test - txn #1 : read, modify, persist, refresh related Entity |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult(); |
| assertNotNull(billReRead); |
| BillLine billLineReRead = billReRead.getBillLines().get(0); |
| assertNotNull(billLineReRead); |
| |
| billAction = new BillAction(); |
| billAction.setBillLine(billLineReRead); |
| billAction.setPriority(2); |
| |
| em.persist(billAction); |
| |
| em.refresh(billLineReRead); // refresh |
| |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| // test - txn #2 : read, modify and trigger relationship on related Entity |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| |
| Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult(); |
| billReRead.setStatus(Bill.STATUS_PROCESSING); // DM: if there is no update to Order, issue doesn't occur |
| |
| BillAction billActionReRead = em.createQuery("SELECT a FROM BillAction a where a.id=" + billAction.getId(), BillAction.class).getSingleResult(); |
| assertNotNull(billActionReRead); |
| |
| BillLine billLineReRead = billActionReRead.getBillLine(); |
| assertNotNull(billLineReRead); |
| |
| billLineReRead.getBillLineItems().size(); // Access & trigger BillLine -> BillLineItems list |
| |
| commitTransaction(em); |
| } finally { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| // verify |
| // Failure case: non-null session (a UnitOfWork/RepeatableWriteUnitOfWork) referenced in the wrapped ValueHolder's query. |
| ServerSession srv = getServerSession(); |
| ClassDescriptor descriptor = srv.getDescriptor(billLine); |
| Long blId = billLine.getId(); |
| |
| BillLine cachedBillLine = (BillLine)srv.getIdentityMapAccessor().getFromIdentityMap(blId, BillLine.class); |
| assertNotNull("BillLine from shared cache is null with id: " + blId, cachedBillLine); |
| |
| OneToManyMapping mapping = (OneToManyMapping)srv.getDescriptor(cachedBillLine).getMappingForAttributeName("billLineItems"); |
| IndirectContainer billLineItemsVH = (IndirectContainer) mapping.getAttributeValueFromObject(cachedBillLine); |
| assertNotNull("BillLineItems ValueHolder should not be null", billLineItemsVH); |
| |
| ValueHolderInterface wrappedVH = billLineItemsVH.getValueHolder(); |
| assertNotNull("Wrapped ValueHolder should not be null", wrappedVH); |
| |
| if (wrappedVH instanceof QueryBasedValueHolder) { |
| DatabaseQuery query = ((QueryBasedValueHolder)wrappedVH).getQuery(); |
| if (query.getSession() != null && query.getSession().isUnitOfWork()) { |
| fail("UnitOfWork referenced in Query from wrapped QueryBasedValueHolder in shared cache"); |
| } |
| } |
| } finally { |
| // reset |
| em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| bill = em.find(Bill.class, bill.getId()); |
| if (bill != null) { |
| em.remove(bill); |
| } |
| billLine = em.find(BillLine.class, billLine.getId()); |
| if (billLine != null) { |
| em.remove(billLine); |
| } |
| billLineItem = em.find(BillLineItem.class, billLineItem.getId()); |
| if (billLineItem != null) { |
| em.remove(billLineItem); |
| } |
| if (billAction != null) { |
| billAction = em.find(BillAction.class, billAction.getId()); |
| if (billAction != null) { |
| em.remove(billAction); |
| } |
| } |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| } |
| |
| /** |
| * Bug 412056 |
| * Test batch fetch with size smaller than results in reverse order |
| */ |
| public void testEmployeeToProjectWithBatchFetchTypeInReverseIteration() { |
| final String lastName = "testEmployeeToProject"; |
| |
| // Set up |
| Set<Employee> employeesToRemove = new HashSet<>(); |
| EntityManager em = createEntityManager(); |
| for (int i = 0; i < 100; i++) { |
| beginTransaction(em); |
| Employee employee = new Employee(); |
| employee.setLastName(lastName); |
| employeesToRemove.add(employee); |
| em.persist(employee); |
| for (int j = 0; j < 20; j++) { |
| Project project = new Project(); |
| employee.addProject(project); |
| em.persist(project); |
| } |
| commitTransaction(em); |
| } |
| |
| JpaEntityManager jpaEntityManager = (JpaEntityManager) em.getDelegate(); |
| jpaEntityManager.getUnitOfWork().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| try { |
| Expression exp = new ExpressionBuilder(Employee.class); |
| EJBQueryImpl query = (EJBQueryImpl) jpaEntityManager.createQuery(exp, Employee.class); |
| ((ReadAllQuery) query.getDatabaseQuery()).addBatchReadAttribute("projects"); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchType(BatchFetchType.IN); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchSize(10); |
| List<Employee> employees = query.getResultList(); |
| |
| // Trigger the bug |
| Collections.reverse(employees); |
| |
| int count = 0; |
| try { |
| for (Employee employee : employees) { |
| if(lastName.equals(employee.getLastName())) { |
| for (Project project : employee.getProjects()) { |
| count++; |
| } |
| } |
| } |
| Assert.assertEquals("Project objects received are not as many as expected", 2000, count); |
| } catch (ArrayIndexOutOfBoundsException x) { |
| Assert.fail(Helper.printStackTraceToString(x)); |
| } |
| } finally { |
| // Clean up |
| beginTransaction(em); |
| for (Employee employee : employeesToRemove) { |
| employee = em.merge(employee); |
| for (Project project : employee.getProjects()) { |
| em.remove(em.merge(project)); |
| } |
| em.remove(employee); |
| } |
| commitTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 412056 |
| * Test batch fetch with size smaller than results with custom iteration |
| */ |
| public void testEmployeeToProjectWithBatchFetchTypeInCustomIteration() { |
| final String lastName = "testEmployeeToProject"; |
| |
| // Set up |
| Set<Employee> employeesToRemove = new HashSet<>(); |
| EntityManager em = createEntityManager(); |
| for (int i = 0; i < 100; i++) { |
| beginTransaction(em); |
| Employee employee = new Employee(); |
| employee.setLastName(lastName); |
| employeesToRemove.add(employee); |
| em.persist(employee); |
| for (int j = 0; j < 20; j++) { |
| Project project = new Project(); |
| employee.addProject(project); |
| em.persist(project); |
| } |
| commitTransaction(em); |
| } |
| |
| JpaEntityManager jpaEntityManager = (JpaEntityManager) em.getDelegate(); |
| jpaEntityManager.getUnitOfWork().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| try { |
| Expression exp = new ExpressionBuilder(Employee.class); |
| EJBQueryImpl query = (EJBQueryImpl) jpaEntityManager.createQuery(exp, Employee.class); |
| ((ReadAllQuery) query.getDatabaseQuery()).addBatchReadAttribute("projects"); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchType(BatchFetchType.IN); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchSize(10); |
| List<Employee> employees = query.getResultList(); |
| |
| // Trigger the bug |
| employees.add(employees.remove(0)); |
| |
| int count = 0; |
| try { |
| for (Employee employee : employees) { |
| if(lastName.equals(employee.getLastName())) { |
| for (Project project : employee.getProjects()) { |
| count++; |
| } |
| } |
| } |
| Assert.assertEquals("Project objects received are not as many as expected", 2000, count); |
| } catch (ArrayIndexOutOfBoundsException x) { |
| Assert.fail(Helper.printStackTraceToString(x)); |
| } |
| } finally { |
| // Clean up |
| beginTransaction(em); |
| for (Employee employee : employeesToRemove) { |
| employee = em.merge(employee); |
| for (Project project : employee.getProjects()) { |
| em.remove(em.merge(project)); |
| } |
| em.remove(employee); |
| } |
| commitTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 412056 |
| * Test batch fetch with size one less than results in random order |
| */ |
| public void testEmployeeToProjectWithBatchFetchTypeInRandomIteration() { |
| final String lastName = "testRandomEmployeeToProject"; |
| |
| // Set up |
| Set<Employee> employeesToRemove = new HashSet<>(); |
| EntityManager em = createEntityManager(); |
| for (int i = 0; i < 100; i++) { |
| beginTransaction(em); |
| Employee employee = new Employee(); |
| employee.setLastName(lastName); |
| employeesToRemove.add(employee); |
| em.persist(employee); |
| for (int j = 0; j < 20; j++) { |
| Project project = new Project(); |
| employee.addProject(project); |
| em.persist(project); |
| } |
| commitTransaction(em); |
| } |
| |
| JpaEntityManager jpaEntityManager = (JpaEntityManager) em.getDelegate(); |
| jpaEntityManager.getUnitOfWork().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| try { |
| Expression exp = new ExpressionBuilder(Employee.class).get("lastName").equal(lastName); |
| EJBQueryImpl query = (EJBQueryImpl) jpaEntityManager.createQuery(exp, Employee.class); |
| ((ReadAllQuery) query.getDatabaseQuery()).addBatchReadAttribute("projects"); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchType(BatchFetchType.IN); |
| ((ReadAllQuery) query.getDatabaseQuery()).setBatchFetchSize(99); |
| List<Employee> employees = query.getResultList(); |
| |
| // Trigger the bug |
| Collections.shuffle(employees); |
| |
| int count = 0; |
| try { |
| for (Employee employee : employees) { |
| for (Project project : employee.getProjects()) { |
| count++; |
| } |
| } |
| Assert.assertEquals("Project objects received are not as many as expected", 2000, count); |
| } catch (ArrayIndexOutOfBoundsException x) { |
| Assert.fail(Helper.printStackTraceToString(x)); |
| } |
| } finally { |
| // Clean up |
| beginTransaction(em); |
| for (Employee employee : employeesToRemove) { |
| employee = em.merge(employee); |
| for (Project project : employee.getProjects()) { |
| em.remove(em.merge(project)); |
| } |
| em.remove(employee); |
| } |
| commitTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 502085 - @OneToMany with @OrderColumn contains a null element after specific scenario |
| * |
| */ |
| public void testNullValueInCollectionWithOrderColumn() { |
| // Create test data |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| OrderedEntityA newEntityA1 = new OrderedEntityA(1L, "Entity-A1"); |
| OrderedEntityA newEntityA2 = null; // save for later |
| OrderedEntityZ newEntityZ1 = new OrderedEntityZ(1L, "Entity-Z1"); |
| OrderedEntityZ newEntityZ2 = new OrderedEntityZ(2L, "Entity-Z2"); |
| newEntityZ1.addEntityA(newEntityA1); |
| |
| em.persist(newEntityA1); |
| em.persist(newEntityZ1); |
| em.persist(newEntityZ2); |
| |
| commitTransaction(em); |
| closeEntityManager(em); |
| |
| try { |
| // Test |
| em = createEntityManager(); |
| beginTransaction(em); |
| |
| // load Entity Z2 for unrelated modification within same EM |
| OrderedEntityZ entityZ2 = em.createQuery("SELECT z FROM OrderedEntityZ z WHERE z.id = 2", OrderedEntityZ.class).getSingleResult(); |
| entityZ2.setDescription("Entity-Z2-MODIFIED"); // make a change |
| em.persist(entityZ2); // important to persist modification first |
| |
| // load Entity Z1 for modification |
| OrderedEntityZ entityZ1 = em.createQuery("SELECT z FROM OrderedEntityZ z WHERE z.id = 1", OrderedEntityZ.class).getSingleResult(); |
| |
| // Remove A1 from collection, add A2 to collection, persist |
| entityZ1.removeEntityA(entityZ1.getEntityAs().get(0)); |
| newEntityA2 = new OrderedEntityA(2L, "Entity-A2"); |
| entityZ1.addEntityA(newEntityA2); |
| |
| em.persist(newEntityA2); |
| |
| commitTransaction(em); |
| closeEntityManager(em); |
| |
| // Verify |
| em = createEntityManager(); |
| |
| entityZ1 = em.createQuery("SELECT z FROM OrderedEntityZ z WHERE z.id = 1", OrderedEntityZ.class).getSingleResult(); |
| List<OrderedEntityA> entityAList = entityZ1.getEntityAs(); |
| |
| // validate that Entity Z1's collection is size 1 and contains a valid Entity A2 with correct description |
| assertEquals("invalid collection size", 1, entityAList.size()); |
| OrderedEntityA firstEntityA = entityAList.get(0); |
| assertNotNull("null value in collection", firstEntityA); |
| assertEquals("wrong description in entity", newEntityA2.getDescription(), firstEntityA.getDescription()); |
| |
| closeEntityManager(em); |
| } finally { |
| if (em != null && em.isOpen()) { |
| closeEntityManager(em); |
| } |
| // clean up |
| em = createEntityManager(); |
| beginTransaction(em); |
| |
| newEntityA1 = em.find(OrderedEntityA.class, newEntityA1.getId()); |
| if (newEntityA1 != null) { |
| em.remove(newEntityA1); |
| } |
| if (newEntityA2 != null) { |
| newEntityA2 = em.find(OrderedEntityA.class, newEntityA2.getId()); |
| if (newEntityA2 != null) { |
| em.remove(newEntityA2); |
| } |
| } |
| newEntityZ1 = em.find(OrderedEntityZ.class, newEntityZ1.getId()); |
| if (newEntityZ1 != null) { |
| em.remove(newEntityZ1); |
| } |
| newEntityZ2 = em.find(OrderedEntityZ.class, newEntityZ2.getId()); |
| if (newEntityZ2 != null) { |
| em.remove(newEntityZ2); |
| } |
| |
| commitTransaction(em); |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 453865 |
| * Test joining across an @ElementCollection (List collection implementation) with an ORDER BY clause. |
| */ |
| public void testJoinWithOrderByOnElementCollectionList() { |
| EntityManager em = createEntityManager(); |
| try { |
| String jpql = "SELECT resp FROM Employee e JOIN e.responsibilities AS resp " + |
| "WHERE e.lastName = 'Smith' ORDER BY resp"; |
| Query query = em.createQuery(jpql, String.class); |
| List<String> results = query.getResultList(); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Bug 453865 |
| * Test joining across an @ElementCollection (Map collection implementation) with an ORDER BY clause. |
| */ |
| public void testJoinWithOrderByOnElementCollectionMap() { |
| EntityManager em = createEntityManager(); |
| try { |
| String jpql = "SELECT value(mapEntry) FROM Buyer b JOIN b.creditCards mapEntry " + |
| "WHERE key(mapEntry) = 'VI' ORDER BY value(mapEntry)"; |
| Query query = em.createQuery(jpql, Long.class); |
| List<Long> results = query.getResultList(); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| protected int getVersion(EntityManager em, Dealer dealer) { |
| Vector pk = new Vector(1); |
| pk.add(dealer.getId()); |
| |
| return getServerSession().getDescriptor(Dealer.class).getOptimisticLockingPolicy().getWriteLockValue(dealer, pk, getServerSession()); |
| } |
| |
| protected List<Employee> createEmployeesWithUnidirectionalMappings(String lastName) { |
| int n = 2; |
| List<Employee> employees = new ArrayList<Employee>(n); |
| for(int i=0; i<n; i++) { |
| Employee emp = new Employee(); |
| emp.setFirstName(Integer.toString(i+1)); |
| emp.setLastName(lastName); |
| employees.add(emp); |
| for(int j=0; j<n; j++) { |
| Dealer dealer = new Dealer(); |
| dealer.setFirstName(emp.getFirstName() + "_" + (j + 1)); |
| dealer.setLastName(lastName); |
| emp.addDealer(dealer); |
| for(int k=0; k<n; k++) { |
| Customer customer = new Customer(); |
| customer.setFirstName(dealer.getFirstName() + "_" + (k + 1)); |
| customer.setLastName(lastName); |
| dealer.addCustomer(customer); |
| } |
| } |
| } |
| return employees; |
| } |
| |
| protected List<Employee> persistEmployeesWithUnidirectionalMappings(String lastName) { |
| EntityManager em = createEntityManager(); |
| try { |
| return persistEmployeesWithUnidirectionalMappings(lastName, em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| protected List<Employee> persistEmployeesWithUnidirectionalMappings(String lastName, EntityManager em) { |
| List<Employee> employees = createEmployeesWithUnidirectionalMappings(lastName); |
| beginTransaction(em); |
| try { |
| for(int i=0; i<employees.size(); i++) { |
| em.persist(employees.get(i)); |
| } |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| } |
| return employees; |
| } |
| |
| protected void deleteEmployeesWithUnidirectionalMappings(String lastName) { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| em.createQuery("DELETE FROM AdvancedCustomer c WHERE c.lastName = '"+lastName+"'").executeUpdate(); |
| em.createQuery("DELETE FROM Dealer d WHERE d.lastName = '"+lastName+"'").executeUpdate(); |
| Query q = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = '"+lastName+"'"); |
| for (Object oldData : q.getResultList()) { |
| em.remove(oldData); |
| } |
| commitTransaction(em); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| clearCache(); |
| } |
| } |
| } |