mirror of https://github.com/apache/openjpa.git
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:
parent
02846623a8
commit
f9fd4837b3
|
@ -109,15 +109,10 @@ public class HandlerHandlerMapTableFieldStrategy
|
|||
field.mapJoin(adapt, true);
|
||||
_kio = new ColumnIO();
|
||||
List columns = key.getValueInfo().getColumns();
|
||||
if (columns != null && columns.size() > 0) {
|
||||
// MapKeyColumn is used
|
||||
_kcols = HandlerStrategies.map(key, "key", _kio, adapt);
|
||||
} else {
|
||||
DBDictionary dict = field.getMappingRepository().getDBDictionary();
|
||||
_kcols = HandlerStrategies.map(key,
|
||||
dict.getValidColumnName("key", field.getTable()), _kio,
|
||||
adapt);
|
||||
}
|
||||
String colName = dict.getValidColumnName("key", field.getTable());
|
||||
_kcols = HandlerStrategies.map(key, colName, _kio, adapt);
|
||||
|
||||
_vio = new ColumnIO();
|
||||
_vcols = HandlerStrategies.map(val, "value", _vio, adapt);
|
||||
field.mapPrimaryKey(adapt);
|
||||
|
|
|
@ -45,8 +45,10 @@ import javax.persistence.JoinColumn;
|
|||
import javax.persistence.JoinColumns;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.MapKeyEnumerated;
|
||||
import javax.persistence.MapKeyJoinColumn;
|
||||
import javax.persistence.MapKeyJoinColumns;
|
||||
import javax.persistence.MapKeyTemporal;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.PrimaryKeyJoinColumns;
|
||||
import javax.persistence.SecondaryTable;
|
||||
|
@ -145,8 +147,10 @@ public class AnnotationPersistenceMappingParser
|
|||
_tags.put(KeyNonpolymorphic.class, KEY_NONPOLY);
|
||||
_tags.put(KeyStrategy.class, KEY_STRAT);
|
||||
_tags.put(MapKeyColumn.class, MAP_KEY_COL);
|
||||
_tags.put(MapKeyEnumerated.class, MAP_KEY_ENUMERATED);
|
||||
_tags.put(MapKeyJoinColumn.class, MAP_KEY_JOIN_COL);
|
||||
_tags.put(MapKeyJoinColumns.class, MAP_KEY_JOIN_COLS);
|
||||
_tags.put(MapKeyTemporal.class, MAP_KEY_TEMPORAL);
|
||||
_tags.put(PrimaryKeyJoinColumn.class, PK_JOIN_COL);
|
||||
_tags.put(PrimaryKeyJoinColumns.class, PK_JOIN_COLS);
|
||||
_tags.put(SecondaryTable.class, SECONDARY_TABLE);
|
||||
|
@ -1070,6 +1074,9 @@ public class AnnotationPersistenceMappingParser
|
|||
case MAP_KEY_COL:
|
||||
parseMapKeyColumn(fm, (MapKeyColumn) anno);
|
||||
break;
|
||||
case MAP_KEY_ENUMERATED:
|
||||
parseMapKeyEnumerated(fm, (MapKeyEnumerated) anno);
|
||||
break;
|
||||
case MAP_KEY_JOIN_COL:
|
||||
parseMapKeyJoinColumns(fm, (MapKeyJoinColumn) anno);
|
||||
break;
|
||||
|
@ -1091,6 +1098,9 @@ public class AnnotationPersistenceMappingParser
|
|||
case TEMPORAL:
|
||||
parseTemporal(fm, (Temporal) anno);
|
||||
break;
|
||||
case MAP_KEY_TEMPORAL:
|
||||
parseMapKeyTemporal(fm, (MapKeyTemporal) anno);
|
||||
break;
|
||||
case CLASS_CRIT:
|
||||
fm.getValueInfo().setUseClassCriteria
|
||||
(((ClassCriteria) anno).value());
|
||||
|
@ -1350,6 +1360,15 @@ public class AnnotationPersistenceMappingParser
|
|||
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.
|
||||
*/
|
||||
|
@ -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).
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,7 @@ enum MappingTag {
|
|||
JOIN_COL,
|
||||
JOIN_COLS,
|
||||
JOIN_TABLE,
|
||||
MAP_KEY_ENUMERATED,
|
||||
ORDER_COLUMN,
|
||||
PK_JOIN_COL,
|
||||
PK_JOIN_COLS,
|
||||
|
@ -92,6 +93,7 @@ enum MappingTag {
|
|||
MAP_KEY_COL,
|
||||
MAP_KEY_JOIN_COL,
|
||||
MAP_KEY_JOIN_COLS,
|
||||
MAP_KEY_TEMPORAL,
|
||||
MAPPING_OVERRIDE,
|
||||
MAPPING_OVERRIDES,
|
||||
NONPOLY,
|
||||
|
|
|
@ -92,8 +92,10 @@ public class XMLPersistenceMappingParser
|
|||
_elems.put("join-column", JOIN_COL);
|
||||
_elems.put("inverse-join-column", COL);
|
||||
_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-join-column", MAP_KEY_JOIN_COL);
|
||||
_elems.put("map-key-temporal", MAP_KEY_TEMPORAL);
|
||||
_elems.put("order-column", ORDER_COLUMN);
|
||||
_elems.put("primary-key-join-column", PK_JOIN_COL);
|
||||
_elems.put("secondary-table", SECONDARY_TABLE);
|
||||
|
@ -242,6 +244,8 @@ public class XMLPersistenceMappingParser
|
|||
break;
|
||||
case TEMPORAL:
|
||||
case ENUMERATED:
|
||||
case MAP_KEY_ENUMERATED:
|
||||
case MAP_KEY_TEMPORAL:
|
||||
ret = true;
|
||||
break;
|
||||
case SQL_RESULT_SET_MAPPING:
|
||||
|
@ -298,9 +302,15 @@ public class XMLPersistenceMappingParser
|
|||
case TEMPORAL:
|
||||
endTemporal();
|
||||
break;
|
||||
case MAP_KEY_TEMPORAL:
|
||||
endMapKeyTemporal();
|
||||
break;
|
||||
case ENUMERATED:
|
||||
endEnumerated();
|
||||
break;
|
||||
case MAP_KEY_ENUMERATED:
|
||||
endMapKeyEnumerated();
|
||||
break;
|
||||
case SQL_RESULT_SET_MAPPING:
|
||||
endSQLResultSetMapping();
|
||||
break;
|
||||
|
@ -495,6 +505,35 @@ public class XMLPersistenceMappingParser
|
|||
_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.
|
||||
*/
|
||||
|
@ -510,6 +549,21 @@ public class XMLPersistenceMappingParser
|
|||
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
|
||||
protected boolean startLob(Attributes attrs)
|
||||
throws SAXException {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 };
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.openjpa.persistence.embed;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -77,7 +78,8 @@ public class TestEmbeddable extends SingleEMFTestCase {
|
|||
Department1.class, Employee1.class, Department2.class,
|
||||
Employee2.class, EmployeePK2.class, Department3.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,
|
||||
Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class,
|
||||
EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class,
|
||||
|
@ -162,6 +164,16 @@ public class TestEmbeddable extends SingleEMFTestCase {
|
|||
findObjMapKeyClass();
|
||||
}
|
||||
|
||||
public void testMapKeyEnumerated() {
|
||||
createObjMapKeyEnumerated();
|
||||
findObjMapKeyEnumerated();
|
||||
}
|
||||
|
||||
public void testMapKeyTemporal() {
|
||||
createObjMapKeyTemporal();
|
||||
findObjMapKeyTemporal();
|
||||
}
|
||||
|
||||
public void testEntityA_Embed_MappedToOneCascadeDelete() {
|
||||
createEntityA_Embed_MappedToOneCascadeDelete();
|
||||
updateEntityA_Embed_MappedToOneCascadeDelete();
|
||||
|
@ -1577,6 +1589,53 @@ public class TestEmbeddable extends SingleEMFTestCase {
|
|||
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() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
EntityTransaction tran = em.getTransaction();
|
||||
|
@ -1928,6 +1987,28 @@ public class TestEmbeddable extends SingleEMFTestCase {
|
|||
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) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
EntityTransaction tran = em.getTransaction();
|
||||
|
|
Loading…
Reference in New Issue