mirror of https://github.com/apache/openjpa.git
Reverting OPENJPA_817 in trunk. Conflict with Issue 706 causes unpredictable results
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@723914 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b45e0655df
commit
7a6ac4afc7
|
@ -58,7 +58,7 @@ public class ConstraintUpdateManager
|
||||||
(ConstraintUpdateManager.class);
|
(ConstraintUpdateManager.class);
|
||||||
|
|
||||||
public boolean orderDirty() {
|
public boolean orderDirty() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PreparedStatementManager newPreparedStatementManager
|
protected PreparedStatementManager newPreparedStatementManager
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -39,17 +39,17 @@ import org.apache.openjpa.util.InternalException;
|
||||||
public class RowManagerImpl
|
public class RowManagerImpl
|
||||||
implements RowManager {
|
implements RowManager {
|
||||||
|
|
||||||
private Map<Key, PrimaryRow> _inserts = null;
|
private Map _inserts = null;
|
||||||
private Map<Key, PrimaryRow> _updates = null;
|
private Map _updates = null;
|
||||||
private Map<Key, PrimaryRow> _deletes = null;
|
private Map _deletes = null;
|
||||||
private Collection<SecondaryRow> _secondaryUpdates = null;
|
private Collection _secondaryUpdates = null;
|
||||||
private Collection<SecondaryRow> _secondaryDeletes = null;
|
private Collection _secondaryDeletes = null;
|
||||||
private Collection<Row> _allRowUpdates = null;
|
private Collection _allRowUpdates = null;
|
||||||
private Collection<Row> _allRowDeletes = null;
|
private Collection _allRowDeletes = null;
|
||||||
|
|
||||||
// we maintain a list of the order of all primary rows if the user
|
// we maintain a list of the order of all primary rows if the user
|
||||||
// wants to be able to fetch them in order
|
// wants to be able to fetch them in order
|
||||||
private final List<PrimaryRow> _primaryOrder;
|
private final List _primaryOrder;
|
||||||
|
|
||||||
// track whether we're dealing with any auto-inc columns
|
// track whether we're dealing with any auto-inc columns
|
||||||
private boolean _auto = false;
|
private boolean _auto = false;
|
||||||
|
@ -66,7 +66,7 @@ public class RowManagerImpl
|
||||||
* @param order whether to keep track of the order in which rows are added
|
* @param order whether to keep track of the order in which rows are added
|
||||||
*/
|
*/
|
||||||
public RowManagerImpl(boolean order) {
|
public RowManagerImpl(boolean order) {
|
||||||
_primaryOrder = (order) ? new ArrayList<PrimaryRow>() : null;
|
_primaryOrder = (order) ? new ArrayList() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,98 +80,61 @@ public class RowManagerImpl
|
||||||
* Return the ordered primary rows. Only available if ordering requested
|
* Return the ordered primary rows. Only available if ordering requested
|
||||||
* on construction.
|
* on construction.
|
||||||
*/
|
*/
|
||||||
public List<PrimaryRow> getOrdered() {
|
public List getOrdered() {
|
||||||
if(_primaryOrder == null ) {
|
return (_primaryOrder == null) ? Collections.EMPTY_LIST : _primaryOrder;
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _primaryOrder;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all inserted primary rows.
|
* Return all inserted primary rows.
|
||||||
*/
|
*/
|
||||||
public Collection<PrimaryRow> getInserts() {
|
public Collection getInserts() {
|
||||||
if(_inserts == null ) {
|
return (_inserts == null) ? Collections.EMPTY_LIST : _inserts.values();
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _inserts.values();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all updated primary rows.
|
* Return all updated primary rows.
|
||||||
*/
|
*/
|
||||||
public Collection<PrimaryRow> getUpdates() {
|
public Collection getUpdates() {
|
||||||
if(_updates == null ){
|
return (_updates == null) ? Collections.EMPTY_LIST : _updates.values();
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _updates.values();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all deleted primary rows.
|
* Return all deleted primary rows.
|
||||||
*/
|
*/
|
||||||
public Collection<PrimaryRow> getDeletes() {
|
public Collection getDeletes() {
|
||||||
if(_deletes == null) {
|
return (_deletes == null) ? Collections.EMPTY_LIST : _deletes.values();
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _deletes.values();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all inserted and updated secondary rows.
|
* Return all inserted and updated secondary rows.
|
||||||
*/
|
*/
|
||||||
public Collection<SecondaryRow> getSecondaryUpdates() {
|
public Collection getSecondaryUpdates() {
|
||||||
if(_secondaryUpdates == null) {
|
return (_secondaryUpdates == null) ? Collections.EMPTY_LIST
|
||||||
return Collections.emptyList();
|
: _secondaryUpdates;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _secondaryUpdates;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all deleted secondary rows.
|
* Return all deleted secondary rows.
|
||||||
*/
|
*/
|
||||||
public Collection<SecondaryRow> getSecondaryDeletes() {
|
public Collection getSecondaryDeletes() {
|
||||||
if(_secondaryDeletes == null) {
|
return (_secondaryDeletes == null) ? Collections.EMPTY_LIST
|
||||||
return Collections.emptyList();
|
: _secondaryDeletes;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _secondaryDeletes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return any 'all row' updates.
|
* Return any 'all row' updates.
|
||||||
*/
|
*/
|
||||||
public Collection<Row> getAllRowUpdates() {
|
public Collection getAllRowUpdates() {
|
||||||
if(_allRowUpdates == null) {
|
return (_allRowUpdates == null) ? Collections.EMPTY_LIST
|
||||||
return Collections.emptyList();
|
: _allRowUpdates;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _allRowUpdates;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return any 'all row' deletes.
|
* Return any 'all row' deletes.
|
||||||
*/
|
*/
|
||||||
public Collection<Row> getAllRowDeletes() {
|
public Collection getAllRowDeletes() {
|
||||||
if(_allRowDeletes == null) {
|
return (_allRowDeletes == null) ? Collections.EMPTY_LIST
|
||||||
return Collections.emptyList();
|
: _allRowDeletes;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _allRowDeletes;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row getSecondaryRow(Table table, int action) {
|
public Row getSecondaryRow(Table table, int action) {
|
||||||
|
@ -186,12 +149,12 @@ public class RowManagerImpl
|
||||||
SecondaryRow srow = (SecondaryRow) row;
|
SecondaryRow srow = (SecondaryRow) row;
|
||||||
if (srow.getAction() == Row.ACTION_DELETE) {
|
if (srow.getAction() == Row.ACTION_DELETE) {
|
||||||
if (_secondaryDeletes == null)
|
if (_secondaryDeletes == null)
|
||||||
_secondaryDeletes = new ArrayList<SecondaryRow>();
|
_secondaryDeletes = new ArrayList();
|
||||||
_secondaryDeletes.add((SecondaryRow) srow.clone());
|
_secondaryDeletes.add(srow.clone());
|
||||||
} else {
|
} else {
|
||||||
if (_secondaryUpdates == null)
|
if (_secondaryUpdates == null)
|
||||||
_secondaryUpdates = new ArrayList<SecondaryRow>();
|
_secondaryUpdates = new ArrayList();
|
||||||
_secondaryUpdates.add((SecondaryRow) srow.clone());
|
_secondaryUpdates.add(srow.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,12 +169,12 @@ public class RowManagerImpl
|
||||||
switch (row.getAction()) {
|
switch (row.getAction()) {
|
||||||
case Row.ACTION_UPDATE:
|
case Row.ACTION_UPDATE:
|
||||||
if (_allRowUpdates == null)
|
if (_allRowUpdates == null)
|
||||||
_allRowUpdates = new ArrayList<Row>();
|
_allRowUpdates = new ArrayList();
|
||||||
_allRowUpdates.add(row);
|
_allRowUpdates.add(row);
|
||||||
break;
|
break;
|
||||||
case Row.ACTION_DELETE:
|
case Row.ACTION_DELETE:
|
||||||
if (_allRowDeletes == null)
|
if (_allRowDeletes == null)
|
||||||
_allRowDeletes = new ArrayList<Row>();
|
_allRowDeletes = new ArrayList();
|
||||||
_allRowDeletes.add(row);
|
_allRowDeletes.add(row);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -229,25 +192,25 @@ public class RowManagerImpl
|
||||||
&& _row != null && _row.getAction() == action)
|
&& _row != null && _row.getAction() == action)
|
||||||
return _row;
|
return _row;
|
||||||
|
|
||||||
Map<Key, PrimaryRow> map;
|
Map map;
|
||||||
if (action == Row.ACTION_DELETE) {
|
if (action == Row.ACTION_DELETE) {
|
||||||
if (_deletes == null && create)
|
if (_deletes == null && create)
|
||||||
_deletes = new LinkedHashMap<Key, PrimaryRow>();
|
_deletes = new HashMap();
|
||||||
map = _deletes;
|
map = _deletes;
|
||||||
} else if (action == Row.ACTION_INSERT) {
|
} else if (action == Row.ACTION_INSERT) {
|
||||||
if (_inserts == null && create)
|
if (_inserts == null && create)
|
||||||
_inserts = new LinkedHashMap<Key, PrimaryRow>();
|
_inserts = new HashMap();
|
||||||
map = _inserts;
|
map = _inserts;
|
||||||
} else {
|
} else {
|
||||||
if (_updates == null && create)
|
if (_updates == null && create)
|
||||||
_updates = new LinkedHashMap<Key, PrimaryRow>();
|
_updates = new HashMap();
|
||||||
map = _updates;
|
map = _updates;
|
||||||
}
|
}
|
||||||
if (map == null)
|
if (map == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
_key = new Key(table, sm);
|
_key = new Key(table, sm);
|
||||||
_row = map.get(_key);
|
_row = (PrimaryRow) map.get(_key);
|
||||||
|
|
||||||
if (_row == null && create) {
|
if (_row == null && create) {
|
||||||
_row = new PrimaryRow(table, action, sm);
|
_row = new PrimaryRow(table, action, sm);
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.jdbc.kernel;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Version;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
// Try not to collide with other Employee entities
|
|
||||||
@Table(name = "PER_JDBC_KERN_EMP")
|
|
||||||
public class Employee {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
private String firstName;
|
|
||||||
private String lastName;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "employee", cascade = { CascadeType.MERGE,
|
|
||||||
CascadeType.PERSIST })
|
|
||||||
private Collection<Task> tasks;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstName() {
|
|
||||||
return firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirstName(String firstName) {
|
|
||||||
this.firstName = firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastName() {
|
|
||||||
return lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastName(String lastName) {
|
|
||||||
this.lastName = lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Task> getTasks() {
|
|
||||||
return tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTasks(Collection<Task> tasks) {
|
|
||||||
this.tasks = tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.jdbc.kernel;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Version;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "PER_JDBC_KERN_STORY") // try not to collide
|
|
||||||
public class Story {
|
|
||||||
@Id
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
|
|
||||||
private Task task;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task getTask() {
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTask(Task task) {
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.jdbc.kernel;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Version;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "PER_JDBC_KERN_TASK")
|
|
||||||
// try not to collide
|
|
||||||
public class Task {
|
|
||||||
@Id
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "task", cascade = { CascadeType.MERGE,
|
|
||||||
CascadeType.PERSIST })
|
|
||||||
private Collection<Story> stories;
|
|
||||||
|
|
||||||
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
|
|
||||||
private Employee employee;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Story> getStories() {
|
|
||||||
return stories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStories(Collection<Story> stories) {
|
|
||||||
this.stories = stories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Employee getEmployee() {
|
|
||||||
return employee;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmployee(Employee employee) {
|
|
||||||
this.employee = employee;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.jdbc.kernel;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that insert order is preserved when using the ConstraintUpdateManager
|
|
||||||
* for entities which are not annotated with ForeignKey constraints.
|
|
||||||
*/
|
|
||||||
public class TestInsertOrder extends SQLListenerTestCase {
|
|
||||||
private String empTableName;
|
|
||||||
private String taskTableName;
|
|
||||||
private String storyTableName;
|
|
||||||
|
|
||||||
public void setUp() {
|
|
||||||
setUp(Employee.class, Task.class, Story.class);
|
|
||||||
empTableName = getMapping(Employee.class).getTable().getFullName();
|
|
||||||
taskTableName = getMapping(Task.class).getTable().getFullName();
|
|
||||||
storyTableName = getMapping(Story.class).getTable().getFullName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <P>Persist an Employee entity and allow the cascade to insert the children.
|
|
||||||
* The inserts should be executed in this order, Employee, Task, Story.
|
|
||||||
* </P>
|
|
||||||
*
|
|
||||||
* <P>
|
|
||||||
* Originally this test would pass in some scenarios. I believe the order
|
|
||||||
* relied on the hashcode of the underlying entities.
|
|
||||||
* </P>
|
|
||||||
*/
|
|
||||||
public void testCascadePersist() {
|
|
||||||
Employee e = newTree(10);
|
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
em.getTransaction().begin();
|
|
||||||
em.persist(e);
|
|
||||||
em.getTransaction().commit();
|
|
||||||
em.close();
|
|
||||||
|
|
||||||
assertSQLOrder("INSERT INTO " + empTableName + ".*", "INSERT INTO "
|
|
||||||
+ taskTableName + ".*", "INSERT INTO " + storyTableName + ".*");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge an Employee entity and allow the cascade to insert the children.
|
|
||||||
* The inserts should be executed in this order, Employee, Task, Story.
|
|
||||||
*/
|
|
||||||
public void testCascadeMerge() {
|
|
||||||
Employee e = newTree(11);
|
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
em.getTransaction().begin();
|
|
||||||
em.merge(e);
|
|
||||||
em.getTransaction().commit();
|
|
||||||
em.close();
|
|
||||||
|
|
||||||
assertSQLOrder("INSERT INTO " + empTableName + ".*", "INSERT INTO "
|
|
||||||
+ taskTableName + ".*", "INSERT INTO " + storyTableName + ".*");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to create a tree of entities
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* ID for the entities.
|
|
||||||
* @return an unmanaged Employee instance with the appropriate relationships
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
private Employee newTree(int id) {
|
|
||||||
Employee e = new Employee();
|
|
||||||
e.setId(id);
|
|
||||||
|
|
||||||
Task t = new Task();
|
|
||||||
t.setId(id);
|
|
||||||
|
|
||||||
Story s = new Story();
|
|
||||||
s.setId(id);
|
|
||||||
|
|
||||||
Collection<Task> tasks = new ArrayList<Task>();
|
|
||||||
tasks.add(t);
|
|
||||||
|
|
||||||
Collection<Story> stories = new ArrayList<Story>();
|
|
||||||
stories.add(s);
|
|
||||||
|
|
||||||
e.setTasks(tasks);
|
|
||||||
t.setEmployee(e);
|
|
||||||
|
|
||||||
t.setStories(stories);
|
|
||||||
s.setTask(t);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,6 +21,7 @@ package org.apache.openjpa.persistence.test;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
|
import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
|
||||||
import org.apache.openjpa.lib.jdbc.JDBCEvent;
|
import org.apache.openjpa.lib.jdbc.JDBCEvent;
|
||||||
|
@ -33,7 +34,7 @@ import org.apache.openjpa.lib.jdbc.JDBCListener;
|
||||||
*/
|
*/
|
||||||
public abstract class SQLListenerTestCase
|
public abstract class SQLListenerTestCase
|
||||||
extends SingleEMFTestCase {
|
extends SingleEMFTestCase {
|
||||||
private static String _nl = System.getProperty("line.separator");
|
|
||||||
protected List<String> sql = new ArrayList<String>();
|
protected List<String> sql = new ArrayList<String>();
|
||||||
protected int sqlCount;
|
protected int sqlCount;
|
||||||
|
|
||||||
|
@ -129,28 +130,4 @@ public abstract class SQLListenerTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertSQLOrder(String... expected) {
|
|
||||||
int hits = 0;
|
|
||||||
|
|
||||||
for (String executedSQL : sql) {
|
|
||||||
if (executedSQL.matches(expected[hits])) {
|
|
||||||
hits++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hits != expected.length) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Did not find SQL in expected order : ").append(_nl);
|
|
||||||
for (String s : expected) {
|
|
||||||
sb.append(s).append(_nl);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("SQL Statements issued : ");
|
|
||||||
for (String s : sql) {
|
|
||||||
sb.append(s).append(_nl);
|
|
||||||
}
|
|
||||||
fail(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue