Anonymous | Login | Signup for a new account | 12-17-2024 08:54 PST |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ View Advanced ] [ Issue History ] [ Print ] | ||||||||
ID | Category | Severity | Reproducibility | Date Submitted | Last Update | ||||
0003335 | [Resin] | major | always | 02-11-09 08:25 | 09-11-09 15:42 | ||||
Reporter | rdhauwe | View Status | public | ||||||
Assigned To | ferg | ||||||||
Priority | normal | Resolution | fixed | ||||||
Status | closed | Product Version | 4.0.0 | ||||||
Summary | 0003335: ManyToOne mapping impossible if primary key defined in super class entity | ||||||||
Description |
I am using a class AbstractEntity defining the primary key of my entities: @MappedSuperclass public class AbstractEntity { private Integer id; @Id @Column(name = "ID") @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } I don't define the primary key in entities A and B inheriting from AbstractEntity. When defining a ManyToOne relationship from B to A, Resin gives the following error message at startup/deployment: [17:21:10.156] {http--8080-15} B.getA: Number of @JoinColumns for 'a' (1) does not match the number of primary key columns for 'A' (0). The annotation is as follows on B: @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "A_ID") public A getA() { return a; } The cause seems to be the fact that the primary key of A is defined/annotated in the superclass AbstractEntity, and not in the class A itself. |
||||||||
Additional Information | |||||||||
Attached Files |
C:\Java\workspace\aclvb\resin\src\com\caucho\amber\cfg\AbstractRelationConfig.java [^] (8,914 bytes) 02-12-09 05:32 C:\Java\workspace\aclvb\resin\src\com\caucho\amber\field\Id.java [^] (12,241 bytes) 02-12-09 05:32 |
||||||||
|
Notes | |
(0003823) rdhauwe 02-12-09 03:57 edited on: 02-12-09 03:57 |
Some debugging information from AbstractRelationConfig.validateJoinColumns(...) [12:55:55.765] {main} EntityType[B] field ManyToOneField[a,EntityType[A]] TargetType:SubEntityType[A] TargetType Id:com.caucho.amber.field.Id@1cfd3b2 columns 0 ParentType:MappedSuperclassType[AbstractEntity] ParentType Id:com.caucho.amber.field.Id@1cfd3b2 columns 0 (<<-- SHOULD BE 1) |
(0003824) rdhauwe 02-12-09 04:17 |
I have looked into the class com.caucho.amber.field.Id. Is it possible that the following code contains a bug? /** * Returns all the keys. */ public int getKeyCount() { return _columns.size(); } Shouldn't this be replaced by : /** * Returns all the keys. */ public int getKeyCount() { return _keys.size(); } |
(0003825) rdhauwe 02-12-09 04:28 |
Id contains the following code, this seems to indicate that _columns remains empty when keys are added to a mapped super class. /** * Adds a new field to the id. */ protected void addKey(IdField key) { _keys.add(key); // ejb/0a04 // Collections.sort(_keys, new AmberFieldCompare()); // jpa/0ge2 if (_ownerType instanceof MappedSuperclassType) return; // jpa/0gg0 if (_ownerType.isAbstractClass()) return; _columns.addAll(key.getColumns()); // Collections.sort(_columns, new ColumnCompare()); for (AmberColumn column : key.getColumns()) { _ownerType.getTable().addIdColumn(column); } } I think the problem is caused by AbstractRelationConfig depending on Id.getColumns() - which is empty for a mapped super class - and doesn't use Id.getKeyCount() nor Id.getKeys(). |
(0003826) rdhauwe 02-12-09 05:30 |
The bug is indeed fixed with the following code, I will upload these 2 files. Id: /** * Returns all the keys. */ public int getKeyCount() { return _keys.size(); } AbstractRelationConfig: void validateJoinColumns(AccessibleObject field, String fieldName, HashMap<String,JoinColumnConfig> joinColumnMap, EntityType targetType) throws ConfigException { if (joinColumnMap == null) return; com.caucho.amber.field.Id id = targetType.getId(); EntityType parentType = targetType; int idCols; // XXX: jpa/0l48 while ((idCols = id.getKeyCount()) == 0) { parentType = parentType.getParentType(); if (parentType == null) break; id = parentType.getId(); } int size; Object joinColumnCfg[] = null; size = joinColumnMap.size(); joinColumnCfg = joinColumnMap.values().toArray(); if (idCols != size) { throw error(field, L.l("Number of @JoinColumns for '{1}' ({0}) does not match the number of primary key columns for '{3}' ({2}).", "" + size, fieldName, idCols, targetType.getName())); } for (int i = 0; i < size; i++) { String ref; ref = ((JoinColumnConfig) joinColumnCfg[i]).getReferencedColumnName(); if (((ref == null) || ref.equals("")) && size > 1) throw error(field, L.l("referencedColumnName is required when more than one @JoinColumn is specified.")); IdField key = findKey(id.getKeys(), ref); if (key == null) throw error(field, L.l("referencedColumnName '{0}' does not match any key column in '{1}'.", ref, targetType.getName())); } } static IdField findKey(ArrayList<IdField> arrayList, String ref) { if (((ref == null) || ref.equals("")) && arrayList.size() == 1) return arrayList.get(0); for (IdField column : arrayList) { if (column.getName().equals(ref)) { return column; } } return null; } |
(0004242) ferg 09-11-09 15:42 |
jpa/1910 |
Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
43 total queries executed. 30 unique queries executed. |