mirror of https://github.com/apache/openjpa.git
OPENJPA-272. Committing the changes to allow @GeneratedValue to detect and report if initial values and/or setters were called on fields marked with @GeneratedValue. New testcases were also provided.
Also had to update an existing testcase (TestSharedMappedSuperclassIdValue) and associated Entities because it was breaking the contract put in place. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@562987 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c34fb4e80e
commit
9382677eb1
|
@ -574,10 +574,15 @@ public class StateManagerImpl
|
|||
return assign && assignObjectId(!preFlushing, preFlushing);
|
||||
}
|
||||
|
||||
// don't assign values to fields with non-default values already
|
||||
if (fmd.getValueStrategy() == ValueStrategies.NONE
|
||||
|| !isDefaultValue(field))
|
||||
// Just return if there's no value generation strategy
|
||||
if (fmd.getValueStrategy() == ValueStrategies.NONE)
|
||||
return false;
|
||||
|
||||
// Throw exception if field already has a value assigned.
|
||||
// @GeneratedValue overrides POJO initial values and setter methods
|
||||
if (!isDefaultValue(field) && !fmd.is_generated())
|
||||
throw new InvalidStateException(_loc.get(
|
||||
"existing-value-override-excep", fmd.getFullName(false)));
|
||||
|
||||
// for primary key fields, assign the object id and recache so that
|
||||
// to the user, so it looks like the oid always matches the pk fields
|
||||
|
@ -585,8 +590,10 @@ public class StateManagerImpl
|
|||
return assignObjectId(!preFlushing, preFlushing);
|
||||
|
||||
// for other fields just assign the field or flush if needed
|
||||
if (_broker.getStoreManager().assignField(this, field, preFlushing))
|
||||
if (_broker.getStoreManager().assignField(this, field, preFlushing)) {
|
||||
fmd.set_generated(true);
|
||||
return true;
|
||||
}
|
||||
if (!preFlushing)
|
||||
_broker.flush();
|
||||
return !preFlushing;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.openjpa.enhance.PersistenceCapable;
|
|||
import org.apache.openjpa.enhance.Reflection;
|
||||
import org.apache.openjpa.kernel.ObjectIdStateManager;
|
||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||
import org.apache.openjpa.kernel.StateManagerImpl;
|
||||
import org.apache.openjpa.kernel.StoreManager;
|
||||
import org.apache.openjpa.lib.util.J2DoPrivHelper;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
|
@ -49,6 +50,8 @@ public class ApplicationIds {
|
|||
|
||||
private static final Localizer _loc = Localizer.forPackage
|
||||
(ApplicationIds.class);
|
||||
private static final Localizer _loc2 = Localizer.forPackage
|
||||
(StateManagerImpl.class);
|
||||
|
||||
/**
|
||||
* Return the primary key values for the given object id. The values
|
||||
|
@ -430,15 +433,25 @@ public class ApplicationIds {
|
|||
}
|
||||
|
||||
/**
|
||||
* Assign generated values to given fields.
|
||||
* Assign generated values to given primary key fields.
|
||||
*/
|
||||
private static boolean assign(OpenJPAStateManager sm, StoreManager store,
|
||||
FieldMetaData[] pks, boolean preFlush) {
|
||||
for (int i = 0; i < pks.length; i++)
|
||||
if (pks[i].getValueStrategy() != ValueStrategies.NONE
|
||||
&& sm.isDefaultValue(pks[i].getIndex())
|
||||
&& !store.assignField(sm, pks[i].getIndex(), preFlush))
|
||||
return false;
|
||||
// If we are generating values...
|
||||
if (pks[i].getValueStrategy() != ValueStrategies.NONE) {
|
||||
// If a value already exists on this field, throw exception.
|
||||
// This is considered an application coding error.
|
||||
if (!sm.isDefaultValue(pks[i].getIndex()))
|
||||
throw new InvalidStateException(_loc2.get(
|
||||
"existing-value-override-excep", pks[i]
|
||||
.getFullName(false)));
|
||||
// Assign the generated value
|
||||
if (store.assignField(sm, pks[i].getIndex(), preFlush))
|
||||
pks[i].set_generated(true);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -368,3 +368,8 @@ null-fg: Attempt to add null/empty fetch group name to fetch configuration.
|
|||
null-field: Attempt to add null/empty field name to fetch configuration.
|
||||
container-projection: Query projections cannot include array, collection, or \
|
||||
map fields. Invalid query: "{0}"
|
||||
existing-value-override-excep: The generated value processing detected an \
|
||||
existing value assigned to this field: {0}. This existing value was either \
|
||||
provided via an initializer or by calling the setter method. You either need \
|
||||
to remove the @GeneratedValue annotation or modify the code to remove the \
|
||||
initializer processing.
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.generationtype;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class GeneratedValues {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@GeneratedValue
|
||||
private long field;
|
||||
|
||||
public GeneratedValues() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GeneratedValues(int id, long field) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(long field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.generationtype;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.InvalidStateException;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
public class TestGeneratedValues extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() {
|
||||
setUp(GeneratedValues.class, CLEAR_TABLES);
|
||||
}
|
||||
|
||||
public void testDefaultValues() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues();
|
||||
GeneratedValues gv2 = new GeneratedValues();
|
||||
|
||||
em.getTransaction().begin();
|
||||
em.persist(gv);
|
||||
em.persist(gv2);
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.refresh(gv);
|
||||
em.refresh(gv2);
|
||||
|
||||
assertFalse(gv.getId() == gv2.getId());
|
||||
assertFalse(gv.getField() == gv2.getField());
|
||||
}
|
||||
|
||||
public void testInitialValues() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues(7, 9);
|
||||
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
em.persist(gv);
|
||||
em.getTransaction().commit();
|
||||
} catch (InvalidStateException ise) {
|
||||
// expected result
|
||||
return;
|
||||
}
|
||||
|
||||
// should not get here...
|
||||
fail();
|
||||
}
|
||||
|
||||
public void testIdSetter() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues();
|
||||
gv.setId(3);
|
||||
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
em.persist(gv);
|
||||
em.getTransaction().commit();
|
||||
} catch (InvalidStateException ise) {
|
||||
// expected result
|
||||
return;
|
||||
}
|
||||
|
||||
// should not get here...
|
||||
fail();
|
||||
}
|
||||
|
||||
public void testFieldSetter() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues();
|
||||
gv.setField(5);
|
||||
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
em.persist(gv);
|
||||
em.getTransaction().commit();
|
||||
} catch (InvalidStateException ise) {
|
||||
// expected result
|
||||
return;
|
||||
}
|
||||
|
||||
// should not get here...
|
||||
fail();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.inheritance;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class NoGenEntityL3
|
||||
extends NoGenMappedSuperclassL2 {
|
||||
|
||||
private int l3data;
|
||||
|
||||
public int getL3Data() {
|
||||
return l3data;
|
||||
}
|
||||
|
||||
public void setL3Data(int data) {
|
||||
l3data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.inheritance;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class NoGenEntityL3Sibling
|
||||
extends NoGenMappedSuperclassL2 {
|
||||
|
||||
private int siblingl3data;
|
||||
|
||||
public int getSiblingL3Data() {
|
||||
return siblingl3data;
|
||||
}
|
||||
|
||||
public void setSiblingL3Data(int data) {
|
||||
siblingl3data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.inheritance;
|
||||
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
@MappedSuperclass
|
||||
public class NoGenMappedSuperclassBase {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.inheritance;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
@MappedSuperclass
|
||||
public class NoGenMappedSuperclassL2
|
||||
extends NoGenMappedSuperclassBase {
|
||||
|
||||
private int l2data;
|
||||
|
||||
public int getL2Data() {
|
||||
return l2data;
|
||||
}
|
||||
|
||||
public void setL2Data(int data) {
|
||||
l2data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -33,15 +33,16 @@ public class TestSharedMappedSuperclassIdValue
|
|||
extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() {
|
||||
setUp(MappedSuperclassBase.class, MappedSuperclassL2.class,
|
||||
EntityL3.class, EntityL3Sibling.class);
|
||||
setUp(CLEAR_TABLES, NoGenMappedSuperclassBase.class,
|
||||
NoGenMappedSuperclassL2.class, NoGenEntityL3.class,
|
||||
NoGenEntityL3Sibling.class);
|
||||
|
||||
EntityL3 ent = new EntityL3();
|
||||
ent.setId(1);
|
||||
NoGenEntityL3 ent = new NoGenEntityL3();
|
||||
ent.setId(1L);
|
||||
ent.setL2Data(99);
|
||||
ent.setL3Data(100);
|
||||
EntityL3Sibling sib = new EntityL3Sibling();
|
||||
sib.setId(1);
|
||||
NoGenEntityL3Sibling sib = new NoGenEntityL3Sibling();
|
||||
sib.setId(1L);
|
||||
sib.setL2Data(100);
|
||||
sib.setSiblingL3Data(101);
|
||||
|
||||
|
@ -55,12 +56,12 @@ public class TestSharedMappedSuperclassIdValue
|
|||
|
||||
public void testFind() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
EntityL3 ent = em.find(EntityL3.class, 1L);
|
||||
NoGenEntityL3 ent = em.find(NoGenEntityL3.class, 1L);
|
||||
assertNotNull(ent);
|
||||
assertEquals(99, ent.getL2Data());
|
||||
assertEquals(100, ent.getL3Data());
|
||||
|
||||
EntityL3Sibling sib = em.find(EntityL3Sibling.class, 1L);
|
||||
NoGenEntityL3Sibling sib = em.find(NoGenEntityL3Sibling.class, 1L);
|
||||
assertNotNull(sib);
|
||||
assertEquals(100, sib.getL2Data());
|
||||
assertEquals(101, sib.getSiblingL3Data());
|
||||
|
@ -70,10 +71,10 @@ public class TestSharedMappedSuperclassIdValue
|
|||
|
||||
public void testGetReference() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
EntityL3 ent = em.getReference(EntityL3.class, 1L);
|
||||
NoGenEntityL3 ent = em.getReference(NoGenEntityL3.class, 1L);
|
||||
assertNotNull(ent);
|
||||
|
||||
EntityL3Sibling sib = em.getReference(EntityL3Sibling.class, 1L);
|
||||
NoGenEntityL3Sibling sib = em.getReference(NoGenEntityL3Sibling.class, 1L);
|
||||
assertNotNull(sib);
|
||||
|
||||
assertEquals(99, ent.getL2Data());
|
||||
|
|
Loading…
Reference in New Issue