mirror of https://github.com/apache/openjpa.git
OPENJPA-871: support JoinColumn in conjunction with MapsId annotation
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@828889 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
13c88d75cf
commit
b646b8810d
|
@ -93,6 +93,8 @@ public class FieldMapping
|
||||||
private ForeignKey _bi_1ToM_Join_FK = null;
|
private ForeignKey _bi_1ToM_Join_FK = null;
|
||||||
private ForeignKey _bi_1ToM_Elem_FK = null;
|
private ForeignKey _bi_1ToM_Elem_FK = null;
|
||||||
|
|
||||||
|
private boolean _hasMapsIdCols = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
|
@ -1335,4 +1337,12 @@ public class FieldMapping
|
||||||
public boolean isNonDefaultMappingUsingJoinTableStrategy() {
|
public boolean isNonDefaultMappingUsingJoinTableStrategy() {
|
||||||
return isBi1To1JT() || isUni1To1JT() || isUniMTo1JT() || isBiMTo1JT();
|
return isBi1To1JT() || isUni1To1JT() || isUniMTo1JT() || isBiMTo1JT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMapsIdCols(boolean hasMapsIdCols) {
|
||||||
|
_hasMapsIdCols = hasMapsIdCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMapsIdCols() {
|
||||||
|
return _hasMapsIdCols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -544,6 +544,10 @@ public abstract class MappingInfo
|
||||||
// n columns because we don't know which of the n columns the info
|
// n columns because we don't know which of the n columns the info
|
||||||
// applies to
|
// applies to
|
||||||
List given = getColumns();
|
List given = getColumns();
|
||||||
|
|
||||||
|
if (context instanceof FieldMapping && ((FieldMapping)context).hasMapsIdCols())
|
||||||
|
given = ((FieldMapping)context).getValueInfo().getMapsIdColumns();
|
||||||
|
|
||||||
boolean fill = ((MappingRepository) context.getRepository()).
|
boolean fill = ((MappingRepository) context.getRepository()).
|
||||||
getMappingDefaults().defaultMissingInfo();
|
getMappingDefaults().defaultMissingInfo();
|
||||||
if ((!given.isEmpty() || (!adapt && !fill))
|
if ((!given.isEmpty() || (!adapt && !fill))
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.openjpa.jdbc.sql.Select;
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
import org.apache.openjpa.lib.util.Localizer;
|
||||||
import org.apache.openjpa.meta.JavaTypes;
|
import org.apache.openjpa.meta.JavaTypes;
|
||||||
|
import org.apache.openjpa.meta.ValueMetaData;
|
||||||
import org.apache.openjpa.meta.ValueMetaDataImpl;
|
import org.apache.openjpa.meta.ValueMetaDataImpl;
|
||||||
import org.apache.openjpa.util.InternalException;
|
import org.apache.openjpa.util.InternalException;
|
||||||
import org.apache.openjpa.util.MetaDataException;
|
import org.apache.openjpa.util.MetaDataException;
|
||||||
|
@ -459,6 +460,11 @@ public class ValueMappingImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void copy(ValueMetaData vmd) {
|
||||||
|
super.copy(vmd);
|
||||||
|
copyMappingInfo((ValueMapping)vmd);
|
||||||
|
}
|
||||||
|
|
||||||
public void copyMappingInfo(ValueMapping vm) {
|
public void copyMappingInfo(ValueMapping vm) {
|
||||||
setValueMappedBy(vm.getValueMappedBy());
|
setValueMappedBy(vm.getValueMappedBy());
|
||||||
setPolymorphic(vm.getPolymorphic());
|
setPolymorphic(vm.getPolymorphic());
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.jdbc.meta;
|
package org.apache.openjpa.jdbc.meta;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.openjpa.jdbc.schema.Column;
|
import org.apache.openjpa.jdbc.schema.Column;
|
||||||
|
@ -47,6 +48,7 @@ public class ValueMappingInfo
|
||||||
|
|
||||||
private boolean _criteria = false;
|
private boolean _criteria = false;
|
||||||
private boolean _canNull = true;
|
private boolean _canNull = true;
|
||||||
|
private List _mapsIdCols = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to use class criteria when joining to related type.
|
* Whether to use class criteria when joining to related type.
|
||||||
|
@ -331,4 +333,18 @@ public class ValueMappingInfo
|
||||||
if (_canNull)
|
if (_canNull)
|
||||||
_canNull = vinfo.canIndicateNull();
|
_canNull = vinfo.canIndicateNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raw column data.
|
||||||
|
*/
|
||||||
|
public List getMapsIdColumns() {
|
||||||
|
return (_mapsIdCols == null) ? Collections.EMPTY_LIST : _mapsIdCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raw column data.
|
||||||
|
*/
|
||||||
|
public void setMapsIdColumns(List cols) {
|
||||||
|
_mapsIdCols = cols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,7 @@ public abstract class EmbedValueHandler
|
||||||
Column[] pkCols = ((ValueMappingImpl)fmd.getValue()).getColumns();
|
Column[] pkCols = ((ValueMappingImpl)fmd.getValue()).getColumns();
|
||||||
for (int j = 0; j < pkCols.length; j++) {
|
for (int j = 0; j < pkCols.length; j++) {
|
||||||
Column newCol = new Column();
|
Column newCol = new Column();
|
||||||
newCol.setName(pkCols[j].getName());
|
newCol.copy(pkCols[j]);
|
||||||
cols.add(newCol);
|
cols.add(newCol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.openjpa.jdbc.kernel.JDBCStore;
|
import org.apache.openjpa.jdbc.kernel.JDBCStore;
|
||||||
|
import org.apache.openjpa.jdbc.meta.ClassMapping;
|
||||||
|
import org.apache.openjpa.jdbc.meta.FieldMapping;
|
||||||
import org.apache.openjpa.jdbc.meta.ValueMapping;
|
import org.apache.openjpa.jdbc.meta.ValueMapping;
|
||||||
import org.apache.openjpa.jdbc.schema.Column;
|
import org.apache.openjpa.jdbc.schema.Column;
|
||||||
import org.apache.openjpa.jdbc.schema.ColumnIO;
|
import org.apache.openjpa.jdbc.schema.ColumnIO;
|
||||||
|
@ -46,6 +48,7 @@ public class ObjectIdValueHandler
|
||||||
boolean adapt) {
|
boolean adapt) {
|
||||||
List cols = new ArrayList();
|
List cols = new ArrayList();
|
||||||
List args = new ArrayList();
|
List args = new ArrayList();
|
||||||
|
setMapsIdCol(vm);
|
||||||
super.map(vm, name, io, adapt, cols, args);
|
super.map(vm, name, io, adapt, cols, args);
|
||||||
|
|
||||||
vm.setColumns((Column[]) cols.toArray(new Column[cols.size()]));
|
vm.setColumns((Column[]) cols.toArray(new Column[cols.size()]));
|
||||||
|
@ -53,6 +56,85 @@ public class ObjectIdValueHandler
|
||||||
return vm.getColumns();
|
return vm.getColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setMapsIdCol(ValueMapping vm) {
|
||||||
|
if (!(vm instanceof FieldMapping))
|
||||||
|
return;
|
||||||
|
if (!((FieldMapping)vm).hasMapsIdCols())
|
||||||
|
return;
|
||||||
|
ClassMapping embeddedMeta = (ClassMapping)((FieldMapping)vm).getValue().getEmbeddedMetaData();
|
||||||
|
if (embeddedMeta == null)
|
||||||
|
return;
|
||||||
|
List mapsIdColList = ((FieldMapping)vm).getValueInfo().getMapsIdColumns();
|
||||||
|
if (mapsIdColList.size() > 0 ) {
|
||||||
|
setMapsIdCols(mapsIdColList, embeddedMeta);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldMapping[] fmds = embeddedMeta.getFieldMappings();
|
||||||
|
for (int i = 0; i < fmds.length; i++) {
|
||||||
|
mapsIdColList = fmds[i].getValueInfo().getMapsIdColumns();
|
||||||
|
if (mapsIdColList.size() == 0)
|
||||||
|
continue;
|
||||||
|
ClassMapping embeddedMeta1 = (ClassMapping)fmds[i].getEmbeddedMetaData();
|
||||||
|
if (embeddedMeta1 != null)
|
||||||
|
setMapsIdCols(mapsIdColList, embeddedMeta1);
|
||||||
|
else
|
||||||
|
setMapsIdCols(mapsIdColList, fmds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMapsIdCols(List cols, ClassMapping cm) {
|
||||||
|
for (int i = 0; i < cols.size(); i++) {
|
||||||
|
String refColName = ((Column)cols.get(i)).getTarget();
|
||||||
|
FieldMapping fm = getReferenceField(cm, refColName);
|
||||||
|
if (fm != null) {
|
||||||
|
List colList1 = new ArrayList();
|
||||||
|
colList1.add(cols.get(i));
|
||||||
|
fm.setMapsIdCols(true);
|
||||||
|
fm.getValueInfo().setMapsIdColumns(colList1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMapsIdCols(List cols, FieldMapping fm) {
|
||||||
|
if (cols.size() == 1) {
|
||||||
|
fm.setMapsIdCols(true);
|
||||||
|
fm.getValueInfo().setMapsIdColumns(cols);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < cols.size(); i++) {
|
||||||
|
String refColName = ((Column)cols.get(i)).getTarget();
|
||||||
|
if (isReferenceField(fm, refColName)) {
|
||||||
|
List colList1 = new ArrayList();
|
||||||
|
colList1.add(cols.get(i));
|
||||||
|
fm.setMapsIdCols(true);
|
||||||
|
fm.getValueInfo().setMapsIdColumns(colList1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FieldMapping getReferenceField(ClassMapping cm, String refColName) {
|
||||||
|
FieldMapping[] fmds = cm.getFieldMappings();
|
||||||
|
for (int i = 0; i < fmds.length; i++) {
|
||||||
|
if (isReferenceField(fmds[i], refColName))
|
||||||
|
return fmds[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isReferenceField(FieldMapping fm, String refColName) {
|
||||||
|
List cols = fm.getValueInfo().getColumns();
|
||||||
|
if (cols.size() == 0) {
|
||||||
|
if (fm.getName().equals(refColName))
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (((Column)cols.get(0)).getName().equals(refColName))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public Object getResultArgument(ValueMapping vm) {
|
public Object getResultArgument(ValueMapping vm) {
|
||||||
return _args;
|
return _args;
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,7 @@ public class RelationFieldStrategy
|
||||||
FieldMapping fm = (FieldMapping) pks[i];
|
FieldMapping fm = (FieldMapping) pks[i];
|
||||||
ValueMappingImpl val = (ValueMappingImpl) field.getValue();
|
ValueMappingImpl val = (ValueMappingImpl) field.getValue();
|
||||||
ValueMappingInfo info = val.getValueInfo();
|
ValueMappingInfo info = val.getValueInfo();
|
||||||
|
if (info.getColumns().size() == 0)
|
||||||
info.setColumns(getMappedByIdColumns(fm));
|
info.setColumns(getMappedByIdColumns(fm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1689,6 +1689,21 @@ public class AnnotationPersistenceMappingParser
|
||||||
setColumns(fm, info, cols, unique);
|
setColumns(fm, info, cols, unique);
|
||||||
if (secondary != null)
|
if (secondary != null)
|
||||||
fm.getMappingInfo().setTableName(secondary);
|
fm.getMappingInfo().setTableName(secondary);
|
||||||
|
String mappedByIdValue = fm.getMappedByIdValue();
|
||||||
|
if (mappedByIdValue != null) {
|
||||||
|
FieldMapping[] pks = fm.getDefiningMapping().getPrimaryKeyFieldMappings();
|
||||||
|
pks[0].setMapsIdCols(true);
|
||||||
|
if (mappedByIdValue.length() == 0) {
|
||||||
|
pks[0].getValueInfo().setMapsIdColumns(cols);
|
||||||
|
} else {
|
||||||
|
ClassMapping embeddedMeta = (ClassMapping)pks[0].getValue().getEmbeddedMetaData();
|
||||||
|
if (embeddedMeta != null) {
|
||||||
|
FieldMapping fmd = embeddedMeta.getFieldMapping(mappedByIdValue);
|
||||||
|
if (fmd != null)
|
||||||
|
fmd.getValueInfo().setMapsIdColumns(cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,13 +22,17 @@ import java.io.Serializable;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.AttributeOverrides;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.EmbeddedId;
|
import javax.persistence.EmbeddedId;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.MapsId;
|
import javax.persistence.MapsId;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
|
|
||||||
|
@ -44,17 +48,22 @@ import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
@Table(name="DI_BOOK1")
|
||||||
@VersionColumn
|
@VersionColumn
|
||||||
public class Book1 implements Serializable {
|
public class Book1 implements Serializable {
|
||||||
@EmbeddedId
|
@EmbeddedId
|
||||||
|
@AttributeOverrides({
|
||||||
|
@AttributeOverride(name="name", column=@Column(name="BOOK_NAME")),
|
||||||
|
@AttributeOverride(name="library", column=@Column(name="LIBRARY_NAME"))
|
||||||
|
})
|
||||||
private BookId1 bid;
|
private BookId1 bid;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "book")
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "book")
|
||||||
private Set<Page1> pages = new HashSet<Page1>();
|
private Set<Page1> pages = new HashSet<Page1>();
|
||||||
|
|
||||||
@MapsId("library")
|
@MapsId("library")
|
||||||
@Column(nullable = false)
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
|
@JoinColumn(name="LIBRARY_NAME", referencedColumnName="LIBRARY_NAME")
|
||||||
private Library1 library;
|
private Library1 library;
|
||||||
|
|
||||||
private String author;
|
private String author;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
@Table(name="DI_LIBRARY1")
|
||||||
@VersionColumn
|
@VersionColumn
|
||||||
public class Library1 implements Serializable {
|
public class Library1 implements Serializable {
|
||||||
@Id
|
@Id
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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.enhance.identity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinColumns;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.MapsId;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity used to test compound primary keys using entity as relationship to
|
||||||
|
* more than one level.
|
||||||
|
*
|
||||||
|
* Test case and domain classes were originally part of the reported issue
|
||||||
|
* <A href="https://issues.apache.org/jira/browse/OPENJPA-207">OPENJPA-207</A>
|
||||||
|
*
|
||||||
|
* @author Jeffrey Blattman
|
||||||
|
* @author Pinaki Poddar
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name="DI_LINE1")
|
||||||
|
@VersionColumn
|
||||||
|
public class Line1 implements Serializable {
|
||||||
|
@EmbeddedId
|
||||||
|
@AttributeOverride(name="lineNum", column=@Column(name="LINE_NUM"))
|
||||||
|
private LineId1 lid;
|
||||||
|
|
||||||
|
@MapsId("page")
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumns({
|
||||||
|
@JoinColumn(name="LIBRARY_NAME", referencedColumnName="LIBRARY_NAME"),
|
||||||
|
@JoinColumn(name="BOOK_NAME", referencedColumnName="BOOK_NAME"),
|
||||||
|
@JoinColumn(name="PAGE_NUM", referencedColumnName="PAGE_NUM")
|
||||||
|
})
|
||||||
|
private Page1 page;
|
||||||
|
|
||||||
|
public LineId1 getLid() {
|
||||||
|
return lid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLid(LineId1 lid) {
|
||||||
|
this.lid = lid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page1 getPage() {
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPage(Page1 page) {
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* 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.enhance.identity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.AttributeOverrides;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity identity used to test compound primary keys using entity as
|
||||||
|
* relationship to more than one level.
|
||||||
|
*
|
||||||
|
* Test case and domain classes were originally part of the reported issue
|
||||||
|
* <A href="https://issues.apache.org/jira/browse/OPENJPA-207">OPENJPA-207</A>
|
||||||
|
*
|
||||||
|
* @author Jeffrey Blattman
|
||||||
|
* @author Pinaki Poddar
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public final class LineId1 implements Serializable {
|
||||||
|
@Column(name="LINE_NUM")
|
||||||
|
private int lineNum;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
@AttributeOverride(name="number", column=@Column(name="PAGE_NUM"))
|
||||||
|
private PageId1 page;
|
||||||
|
|
||||||
|
public LineId1() {}
|
||||||
|
|
||||||
|
public LineId1(int lineNum, PageId1 page) {
|
||||||
|
this.lineNum = lineNum;
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLineNum() {
|
||||||
|
return lineNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineNum(int lineNum) {
|
||||||
|
this.lineNum = lineNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof LineId1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineId1 other = (LineId1)o;
|
||||||
|
|
||||||
|
if (!(getLineNum() == other.getLineNum())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getPage().equals(other.getPage())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return lineNum * (page != null ? getPage().hashCode() : 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageId1 getPage() {
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPage(PageId1 page) {
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,11 @@
|
||||||
package org.apache.openjpa.persistence.enhance.identity;
|
package org.apache.openjpa.persistence.enhance.identity;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.EmbeddedId;
|
import javax.persistence.EmbeddedId;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -27,6 +31,8 @@ import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinColumns;
|
import javax.persistence.JoinColumns;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.MapsId;
|
import javax.persistence.MapsId;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
|
|
||||||
|
@ -42,22 +48,24 @@ import org.apache.openjpa.persistence.jdbc.VersionColumn;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
@Table(name="DI_PAGE1")
|
||||||
@VersionColumn
|
@VersionColumn
|
||||||
public class Page1 implements Serializable {
|
public class Page1 implements Serializable {
|
||||||
@EmbeddedId
|
@EmbeddedId
|
||||||
|
@AttributeOverride(name="number", column=@Column(name="PAGE_NUM"))
|
||||||
private PageId1 pid;
|
private PageId1 pid;
|
||||||
|
|
||||||
@MapsId("book")
|
@MapsId("book")
|
||||||
@Column(nullable = false)
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumns({
|
@JoinColumns({
|
||||||
@JoinColumn(name="BOOK_LIBRARY_LIBRARY_NAME",
|
@JoinColumn(name="LIBRARY_NAME", referencedColumnName="LIBRARY_NAME"),
|
||||||
referencedColumnName="LIBRARY_LIBRARY_NAME"),
|
@JoinColumn(name="BOOK_NAME", referencedColumnName="BOOK_NAME")
|
||||||
@JoinColumn(name="BOOK_BOOK_NAME", referencedColumnName="BOOK_NAME")
|
|
||||||
})
|
})
|
||||||
private Book1 book;
|
private Book1 book;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "page")
|
||||||
|
private Set<Line1> lines = new HashSet<Line1>();
|
||||||
|
|
||||||
public PageId1 getPid() {
|
public PageId1 getPid() {
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
@ -73,4 +81,22 @@ public class Page1 implements Serializable {
|
||||||
public void setBook(Book1 book) {
|
public void setBook(Book1 book) {
|
||||||
this.book = book;
|
this.book = book;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Line1> getLines() {
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line1 getLine(LineId1 lid) {
|
||||||
|
for (Line1 l: lines) {
|
||||||
|
if (l.getLid().equals(lid)) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLine(Line1 l) {
|
||||||
|
l.setPage(this);
|
||||||
|
lines.add(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ package org.apache.openjpa.persistence.enhance.identity;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.AttributeOverrides;
|
||||||
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.Embedded;
|
import javax.persistence.Embedded;
|
||||||
|
|
||||||
|
@ -39,7 +42,12 @@ import javax.persistence.Embedded;
|
||||||
@Embeddable
|
@Embeddable
|
||||||
public final class PageId1 implements Serializable {
|
public final class PageId1 implements Serializable {
|
||||||
private int number;
|
private int number;
|
||||||
|
|
||||||
@Embedded
|
@Embedded
|
||||||
|
@AttributeOverrides({
|
||||||
|
@AttributeOverride(name="name", column=@Column(name="BOOK_NAME")),
|
||||||
|
@AttributeOverride(name="library", column=@Column(name="LIBRARY_NAME"))
|
||||||
|
})
|
||||||
private BookId1 book;
|
private BookId1 book;
|
||||||
|
|
||||||
public PageId1() {}
|
public PageId1() {}
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.persistence.enhance.identity;
|
package org.apache.openjpa.persistence.enhance.identity;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
import org.apache.openjpa.persistence.jdbc.SQLSniffer;
|
||||||
|
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,22 +34,25 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
public class TestMultipleLevelDerivedIdentity1 extends SQLListenerTestCase {
|
||||||
private static String LIBRARY_NAME = "LIB";
|
private static String LIBRARY_NAME = "LIB";
|
||||||
private static String BOOK_NAME = "foo";
|
private static String BOOK_NAME = "foo";
|
||||||
private static int NUM_PAGES = 3;
|
private static int NUM_PAGES = 3;
|
||||||
|
private static int NUM_LINES = 20;
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp(CLEAR_TABLES, Library1.class, Book1.class, Page1.class,
|
super.setUp(DROP_TABLES, Library1.class, Book1.class, Page1.class,
|
||||||
BookId1.class, PageId1.class,
|
BookId1.class, PageId1.class, Line1.class, LineId1.class,
|
||||||
"openjpa.RuntimeUnenhancedClasses", "unsupported");
|
"openjpa.RuntimeUnenhancedClasses", "unsupported");
|
||||||
create();
|
create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPersist() {
|
public void testPersist() {
|
||||||
|
sql.clear();
|
||||||
create();
|
create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQueryRootLevel() {
|
public void testQueryRootLevel() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
List<Library1> list = em.createQuery("SELECT p FROM Library1 p")
|
List<Library1> list = em.createQuery("SELECT p FROM Library1 p")
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
@ -62,6 +67,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQueryIntermediateLevel() {
|
public void testQueryIntermediateLevel() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
List<Book1> list = em.createQuery("SELECT p FROM Book1 p")
|
List<Book1> list = em.createQuery("SELECT p FROM Book1 p")
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
@ -80,6 +86,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQueryLeafLevel() {
|
public void testQueryLeafLevel() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
List<Page1> list = em.createQuery("SELECT p FROM Page1 p")
|
List<Page1> list = em.createQuery("SELECT p FROM Page1 p")
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
@ -95,6 +102,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFindRootNode() {
|
public void testFindRootNode() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
Library1 lib = em.find(Library1.class, LIBRARY_NAME);
|
Library1 lib = em.find(Library1.class, LIBRARY_NAME);
|
||||||
assertNotNull(lib);
|
assertNotNull(lib);
|
||||||
|
@ -106,6 +114,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFindIntermediateNode() {
|
public void testFindIntermediateNode() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
BookId1 bookId = new BookId1();
|
BookId1 bookId = new BookId1();
|
||||||
|
@ -116,6 +125,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFindLeafNode() {
|
public void testFindLeafNode() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
BookId1 bookId = new BookId1();
|
BookId1 bookId = new BookId1();
|
||||||
|
@ -129,6 +139,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdate() {
|
public void testUpdate() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
BookId1 bookId = new BookId1();
|
BookId1 bookId = new BookId1();
|
||||||
|
@ -141,6 +152,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteRoot() {
|
public void testDeleteRoot() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
Library1 lib = em.find(Library1.class, LIBRARY_NAME);
|
Library1 lib = em.find(Library1.class, LIBRARY_NAME);
|
||||||
|
@ -153,6 +165,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteLeafObtainedByQuery() {
|
public void testDeleteLeafObtainedByQuery() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
Page1 page = (Page1)em.createQuery(
|
Page1 page = (Page1)em.createQuery(
|
||||||
|
@ -168,6 +181,7 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteLeafObtainedByFind() {
|
public void testDeleteLeafObtainedByFind() {
|
||||||
|
sql.clear();
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
BookId1 bookId = new BookId1();
|
BookId1 bookId = new BookId1();
|
||||||
|
@ -212,10 +226,36 @@ public class TestMultipleLevelDerivedIdentity1 extends SingleEMFTestCase {
|
||||||
PageId1 pid = new PageId1(i, bid);
|
PageId1 pid = new PageId1(i, bid);
|
||||||
page.setPid(pid);
|
page.setPid(pid);
|
||||||
book.addPage(page);
|
book.addPage(page);
|
||||||
|
for (int j = 1; j <= NUM_LINES; j++) {
|
||||||
|
Line1 line = new Line1();
|
||||||
|
LineId1 lid = new LineId1(j, pid);
|
||||||
|
line.setLid(lid);
|
||||||
|
page.addLine(line);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
em.persist(lib);
|
em.persist(lib);
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
|
||||||
em.clear();
|
em.clear();
|
||||||
|
assertSQLFragnments(sql, "CREATE TABLE DI_LIBRARY1", "LIBRARY_NAME");
|
||||||
|
assertSQLFragnments(sql, "CREATE TABLE DI_BOOK1", "LIBRARY_NAME", "BOOK_NAME");
|
||||||
|
assertSQLFragnments(sql, "CREATE TABLE DI_PAGE1", "LIBRARY_NAME", "BOOK_NAME", "PAGE_NUM");
|
||||||
|
assertSQLFragnments(sql, "CREATE TABLE DI_LINE1", "LIBRARY_NAME", "BOOK_NAME", "PAGE_NUM", "LINE_NUM");
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertSQLFragnments(List<String> list, String... keys) {
|
||||||
|
if (SQLSniffer.matches(list, keys))
|
||||||
|
return;
|
||||||
|
fail("None of the following " + sql.size() + " SQL \r\n" +
|
||||||
|
toString(sql) + "\r\n contains all keys \r\n"
|
||||||
|
+ toString(Arrays.asList(keys)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(List<String> list) {
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
for (String s : list)
|
||||||
|
buf.append(s).append("\r\n");
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue