OPENJPA-1055: add MapKeyTemporal and MapKeyEnumerated support

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@770400 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-04-30 19:07:18 +00:00
parent 02846623a8
commit f9fd4837b3
8 changed files with 388 additions and 11 deletions

View File

@ -109,15 +109,10 @@ public class HandlerHandlerMapTableFieldStrategy
field.mapJoin(adapt, true); field.mapJoin(adapt, true);
_kio = new ColumnIO(); _kio = new ColumnIO();
List columns = key.getValueInfo().getColumns(); List columns = key.getValueInfo().getColumns();
if (columns != null && columns.size() > 0) { DBDictionary dict = field.getMappingRepository().getDBDictionary();
// MapKeyColumn is used String colName = dict.getValidColumnName("key", field.getTable());
_kcols = HandlerStrategies.map(key, "key", _kio, adapt); _kcols = HandlerStrategies.map(key, colName, _kio, adapt);
} else {
DBDictionary dict = field.getMappingRepository().getDBDictionary();
_kcols = HandlerStrategies.map(key,
dict.getValidColumnName("key", field.getTable()), _kio,
adapt);
}
_vio = new ColumnIO(); _vio = new ColumnIO();
_vcols = HandlerStrategies.map(val, "value", _vio, adapt); _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
field.mapPrimaryKey(adapt); field.mapPrimaryKey(adapt);

View File

@ -45,8 +45,10 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns; import javax.persistence.JoinColumns;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.MapKeyColumn; import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.MapKeyJoinColumn; import javax.persistence.MapKeyJoinColumn;
import javax.persistence.MapKeyJoinColumns; import javax.persistence.MapKeyJoinColumns;
import javax.persistence.MapKeyTemporal;
import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.PrimaryKeyJoinColumns; import javax.persistence.PrimaryKeyJoinColumns;
import javax.persistence.SecondaryTable; import javax.persistence.SecondaryTable;
@ -145,8 +147,10 @@ public class AnnotationPersistenceMappingParser
_tags.put(KeyNonpolymorphic.class, KEY_NONPOLY); _tags.put(KeyNonpolymorphic.class, KEY_NONPOLY);
_tags.put(KeyStrategy.class, KEY_STRAT); _tags.put(KeyStrategy.class, KEY_STRAT);
_tags.put(MapKeyColumn.class, MAP_KEY_COL); _tags.put(MapKeyColumn.class, MAP_KEY_COL);
_tags.put(MapKeyEnumerated.class, MAP_KEY_ENUMERATED);
_tags.put(MapKeyJoinColumn.class, MAP_KEY_JOIN_COL); _tags.put(MapKeyJoinColumn.class, MAP_KEY_JOIN_COL);
_tags.put(MapKeyJoinColumns.class, MAP_KEY_JOIN_COLS); _tags.put(MapKeyJoinColumns.class, MAP_KEY_JOIN_COLS);
_tags.put(MapKeyTemporal.class, MAP_KEY_TEMPORAL);
_tags.put(PrimaryKeyJoinColumn.class, PK_JOIN_COL); _tags.put(PrimaryKeyJoinColumn.class, PK_JOIN_COL);
_tags.put(PrimaryKeyJoinColumns.class, PK_JOIN_COLS); _tags.put(PrimaryKeyJoinColumns.class, PK_JOIN_COLS);
_tags.put(SecondaryTable.class, SECONDARY_TABLE); _tags.put(SecondaryTable.class, SECONDARY_TABLE);
@ -1070,6 +1074,9 @@ public class AnnotationPersistenceMappingParser
case MAP_KEY_COL: case MAP_KEY_COL:
parseMapKeyColumn(fm, (MapKeyColumn) anno); parseMapKeyColumn(fm, (MapKeyColumn) anno);
break; break;
case MAP_KEY_ENUMERATED:
parseMapKeyEnumerated(fm, (MapKeyEnumerated) anno);
break;
case MAP_KEY_JOIN_COL: case MAP_KEY_JOIN_COL:
parseMapKeyJoinColumns(fm, (MapKeyJoinColumn) anno); parseMapKeyJoinColumns(fm, (MapKeyJoinColumn) anno);
break; break;
@ -1091,6 +1098,9 @@ public class AnnotationPersistenceMappingParser
case TEMPORAL: case TEMPORAL:
parseTemporal(fm, (Temporal) anno); parseTemporal(fm, (Temporal) anno);
break; break;
case MAP_KEY_TEMPORAL:
parseMapKeyTemporal(fm, (MapKeyTemporal) anno);
break;
case CLASS_CRIT: case CLASS_CRIT:
fm.getValueInfo().setUseClassCriteria fm.getValueInfo().setUseClassCriteria
(((ClassCriteria) anno).value()); (((ClassCriteria) anno).value());
@ -1350,6 +1360,15 @@ public class AnnotationPersistenceMappingParser
fm.getValueInfo().setStrategy(strat); fm.getValueInfo().setStrategy(strat);
} }
/**
* Parse @MapKeyEnumerated.
*/
private void parseMapKeyEnumerated(FieldMapping fm, MapKeyEnumerated anno) {
String strat = EnumValueHandler.class.getName() + "(StoreOrdinal="
+ String.valueOf(anno.value() == EnumType.ORDINAL) + ")";
fm.getKeyMapping().getValueInfo().setStrategy(strat);
}
/** /**
* Parse @Temporal. * Parse @Temporal.
*/ */
@ -1377,6 +1396,33 @@ public class AnnotationPersistenceMappingParser
} }
} }
/**
* Parse @Temporal.
*/
private void parseMapKeyTemporal(FieldMapping fm, MapKeyTemporal anno) {
List cols = fm.getKeyMapping().getValueInfo().getColumns();
if (!cols.isEmpty() && cols.size() != 1)
throw new MetaDataException(_loc.get("num-cols-mismatch", fm,
String.valueOf(cols.size()), "1"));
if (cols.isEmpty()) {
cols = Arrays.asList(new Column[]{ new Column() });
fm.getKeyMapping().getValueInfo().setColumns(cols);
}
Column col = (Column) cols.get(0);
switch (anno.value()) {
case DATE:
col.setType(Types.DATE);
break;
case TIME:
col.setType(Types.TIME);
break;
case TIMESTAMP:
col.setType(Types.TIMESTAMP);
break;
}
}
/** /**
* Parse @Column(s). * Parse @Column(s).
*/ */

View File

@ -49,6 +49,7 @@ enum MappingTag {
JOIN_COL, JOIN_COL,
JOIN_COLS, JOIN_COLS,
JOIN_TABLE, JOIN_TABLE,
MAP_KEY_ENUMERATED,
ORDER_COLUMN, ORDER_COLUMN,
PK_JOIN_COL, PK_JOIN_COL,
PK_JOIN_COLS, PK_JOIN_COLS,
@ -92,6 +93,7 @@ enum MappingTag {
MAP_KEY_COL, MAP_KEY_COL,
MAP_KEY_JOIN_COL, MAP_KEY_JOIN_COL,
MAP_KEY_JOIN_COLS, MAP_KEY_JOIN_COLS,
MAP_KEY_TEMPORAL,
MAPPING_OVERRIDE, MAPPING_OVERRIDE,
MAPPING_OVERRIDES, MAPPING_OVERRIDES,
NONPOLY, NONPOLY,

View File

@ -92,8 +92,10 @@ public class XMLPersistenceMappingParser
_elems.put("join-column", JOIN_COL); _elems.put("join-column", JOIN_COL);
_elems.put("inverse-join-column", COL); _elems.put("inverse-join-column", COL);
_elems.put("join-table", JOIN_TABLE); _elems.put("join-table", JOIN_TABLE);
_elems.put("map-key-enumerated", MAP_KEY_ENUMERATED);
_elems.put("map-key-column", MAP_KEY_COL); _elems.put("map-key-column", MAP_KEY_COL);
_elems.put("map-key-join-column", MAP_KEY_JOIN_COL); _elems.put("map-key-join-column", MAP_KEY_JOIN_COL);
_elems.put("map-key-temporal", MAP_KEY_TEMPORAL);
_elems.put("order-column", ORDER_COLUMN); _elems.put("order-column", ORDER_COLUMN);
_elems.put("primary-key-join-column", PK_JOIN_COL); _elems.put("primary-key-join-column", PK_JOIN_COL);
_elems.put("secondary-table", SECONDARY_TABLE); _elems.put("secondary-table", SECONDARY_TABLE);
@ -242,6 +244,8 @@ public class XMLPersistenceMappingParser
break; break;
case TEMPORAL: case TEMPORAL:
case ENUMERATED: case ENUMERATED:
case MAP_KEY_ENUMERATED:
case MAP_KEY_TEMPORAL:
ret = true; ret = true;
break; break;
case SQL_RESULT_SET_MAPPING: case SQL_RESULT_SET_MAPPING:
@ -298,9 +302,15 @@ public class XMLPersistenceMappingParser
case TEMPORAL: case TEMPORAL:
endTemporal(); endTemporal();
break; break;
case MAP_KEY_TEMPORAL:
endMapKeyTemporal();
break;
case ENUMERATED: case ENUMERATED:
endEnumerated(); endEnumerated();
break; break;
case MAP_KEY_ENUMERATED:
endMapKeyEnumerated();
break;
case SQL_RESULT_SET_MAPPING: case SQL_RESULT_SET_MAPPING:
endSQLResultSetMapping(); endSQLResultSetMapping();
break; break;
@ -495,6 +505,35 @@ public class XMLPersistenceMappingParser
_temporal = Enum.valueOf(TemporalType.class, temp); _temporal = Enum.valueOf(TemporalType.class, temp);
} }
/**
* Parse temporal.
*/
private void endMapKeyTemporal() {
String temp = currentText();
TemporalType _mapKeyTemporal = null;
if (!StringUtils.isEmpty(temp))
_mapKeyTemporal = Enum.valueOf(TemporalType.class, temp);
FieldMapping fm = (FieldMapping) currentElement();
List cols = fm.getKeyMapping().getValueInfo().getColumns();
if (cols.isEmpty()) {
cols = Arrays.asList(new Column[]{ new Column() });
fm.getKeyMapping().getValueInfo().setColumns(cols);
}
Column col = (Column) cols.get(0);
switch (_mapKeyTemporal) {
case DATE:
col.setType(Types.DATE);
break;
case TIME:
col.setType(Types.TIME);
break;
case TIMESTAMP:
col.setType(Types.TIMESTAMP);
break;
}
}
/** /**
* Parse enumerated. * Parse enumerated.
*/ */
@ -510,6 +549,21 @@ public class XMLPersistenceMappingParser
fm.getValueInfo().setStrategy(strat); fm.getValueInfo().setStrategy(strat);
} }
/**
* Parse map-key-enumerated.
*/
private void endMapKeyEnumerated() {
String text = currentText();
if (StringUtils.isEmpty(text))
return;
EnumType type = Enum.valueOf(EnumType.class, text);
FieldMapping fm = (FieldMapping) currentElement();
String strat = EnumValueHandler.class.getName() + "(StoreOrdinal="
+ String.valueOf(type == EnumType.ORDINAL) + ")";
fm.getKeyMapping().getValueInfo().setStrategy(strat);
}
@Override @Override
protected boolean startLob(Attributes attrs) protected boolean startLob(Attributes attrs)
throws SAXException { throws SAXException {

View File

@ -0,0 +1,68 @@
/*
* 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.embed;
import javax.persistence.Embeddable;
@Embeddable
public class FileName4 {
String fName;
String lName;
public FileName4() {}
public FileName4(String fName, String lName) {
this.fName = fName;
this.lName = lName;
}
public String getFName() {
return fName;
}
public void setFName(String fName) {
this.fName = fName;
}
public String getLName() {
return lName;
}
public void setLName(String lName) {
this.lName = lName;
}
public boolean equals(Object o) {
if (!(o instanceof FileName4)) return false;
FileName4 other = (FileName4) o;
if (fName.equals(other.fName) &&
lName.equals(other.lName))
return true;
return false;
}
public int hashCode() {
int ret = 0;
ret += lName.hashCode();
ret = 31 * ret + fName.hashCode();
return ret;
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.embed;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Id;
import javax.persistence.MapKeyEnumerated;
@Entity
public class Item4 {
@Id
int id;
@ElementCollection
@MapKeyEnumerated(EnumType.STRING)
Map<Catagory, FileName4> images = new HashMap<Catagory, FileName4>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Map<Catagory, FileName4> getImages() {
return images;
}
public void addImage(Catagory cat, FileName4 fileName) {
images.put(cat, fileName);
}
public void removeImage(Catagory cat) {
images.remove(cat);
}
public FileName4 getImage(Catagory cat) {
return images.get(cat);
}
public enum Catagory { A1, A2, A3, A4 };
}

View File

@ -0,0 +1,66 @@
/*
* 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.embed;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Id;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.MapKeyTemporal;
import javax.persistence.TemporalType;
@Entity
public class Item5 {
@Id
int id;
@ElementCollection
@MapKeyTemporal(TemporalType.TIME)
Map<Timestamp, FileName4> images = new HashMap<Timestamp, FileName4>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Map<Timestamp, FileName4> getImages() {
return images;
}
public void addImage(Timestamp ts, FileName4 fileName) {
images.put(ts, fileName);
}
public void removeImage(Timestamp ts) {
images.remove(ts);
}
public FileName4 getImage(Timestamp ts) {
return images.get(ts);
}
}

View File

@ -18,6 +18,7 @@
*/ */
package org.apache.openjpa.persistence.embed; package org.apache.openjpa.persistence.embed;
import java.sql.Timestamp;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -77,7 +78,8 @@ public class TestEmbeddable extends SingleEMFTestCase {
Department1.class, Employee1.class, Department2.class, Department1.class, Employee1.class, Department2.class,
Employee2.class, EmployeePK2.class, Department3.class, Employee2.class, EmployeePK2.class, Department3.class,
Employee3.class, EmployeeName3.class, Item1.class, Item2.class, Employee3.class, EmployeeName3.class, Item1.class, Item2.class,
Item3.class, Company1.class, Company2.class, Division.class, Item3.class, Item4.class, Item5.class, FileName4.class,
Company1.class, Company2.class, Division.class,
VicePresident.class, EntityA_Embed_MappedToOne.class, VicePresident.class, EntityA_Embed_MappedToOne.class,
Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class, Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class,
EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class, EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class,
@ -162,6 +164,16 @@ public class TestEmbeddable extends SingleEMFTestCase {
findObjMapKeyClass(); findObjMapKeyClass();
} }
public void testMapKeyEnumerated() {
createObjMapKeyEnumerated();
findObjMapKeyEnumerated();
}
public void testMapKeyTemporal() {
createObjMapKeyTemporal();
findObjMapKeyTemporal();
}
public void testEntityA_Embed_MappedToOneCascadeDelete() { public void testEntityA_Embed_MappedToOneCascadeDelete() {
createEntityA_Embed_MappedToOneCascadeDelete(); createEntityA_Embed_MappedToOneCascadeDelete();
updateEntityA_Embed_MappedToOneCascadeDelete(); updateEntityA_Embed_MappedToOneCascadeDelete();
@ -1576,7 +1588,54 @@ public class TestEmbeddable extends SingleEMFTestCase {
tran.commit(); tran.commit();
em.close(); em.close();
} }
public void createObjMapKeyEnumerated() {
EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction();
Item4 item = new Item4();
item.setId(1);
FileName4 fileName1 = new FileName4("file" + 1, "file" + 1);
item.addImage(Item4.Catagory.A1, fileName1);
FileName4 fileName2 = new FileName4("file" + 2, "file" + 2);
item.addImage(Item4.Catagory.A2, fileName2);
FileName4 fileName3 = new FileName4("file" + 3, "file" + 3);
item.addImage(Item4.Catagory.A3, fileName3);
em.persist(item);
tran.begin();
em.flush();
tran.commit();
em.close();
}
public void createObjMapKeyTemporal() {
EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction();
Item5 item = new Item5();
item.setId(1);
long ts = System.currentTimeMillis();
Timestamp ts1 = new Timestamp(ts);
Timestamp ts2 = new Timestamp(ts+1000000);
Timestamp ts3 = new Timestamp(ts+2000000);
FileName4 fileName1 = new FileName4("file" + 1, "file" + 1);
item.addImage(ts1, fileName1);
FileName4 fileName2 = new FileName4("file" + 2, "file" + 2);
item.addImage(ts2, fileName2);
FileName4 fileName3 = new FileName4("file" + 3, "file" + 3);
item.addImage(ts3, fileName3);
em.persist(item);
tran.begin();
em.flush();
tran.commit();
em.close();
}
public void createObjMapKeyClass() { public void createObjMapKeyClass() {
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction(); EntityTransaction tran = em.getTransaction();
@ -1920,7 +1979,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
int id = vp.getId(); int id = vp.getId();
String name = vp.getName(); String name = vp.getName();
} }
public void queryObjMapKeyClass() { public void queryObjMapKeyClass() {
queryItem(emf); queryItem(emf);
queryCompany(emf); queryCompany(emf);
@ -1928,6 +1987,28 @@ public class TestEmbeddable extends SingleEMFTestCase {
queryVicePresident(emf); queryVicePresident(emf);
} }
public void findObjMapKeyEnumerated() {
EntityManager em = emf.createEntityManager();
Item4 item = em.find(Item4.class, 1);
FileName4 fileName1 = item.getImage(Item4.Catagory.A1);
assertEquals("file1", fileName1.getFName());
assertEquals("file1", fileName1.getLName());
FileName4 fileName2 = item.getImage(Item4.Catagory.A2);
assertEquals("file2", fileName2.getFName());
assertEquals("file2", fileName2.getLName());
FileName4 fileName3 = item.getImage(Item4.Catagory.A3);
assertEquals("file3", fileName3.getFName());
assertEquals("file3", fileName3.getLName());
}
public void findObjMapKeyTemporal() {
EntityManager em = emf.createEntityManager();
Item5 item = em.find(Item5.class, 1);
assertEquals(3, item.getImages().size());
}
public void queryItem(EntityManagerFactory emf) { public void queryItem(EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction(); EntityTransaction tran = em.getTransaction();