1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.hibernate.cfg;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28
29 import org.hibernate.AnnotationException;
30 import org.hibernate.AssertionFailure;
31 import org.hibernate.MappingException;
32 import org.hibernate.mapping.Column;
33 import org.hibernate.mapping.Component;
34 import org.hibernate.mapping.PersistentClass;
35 import org.hibernate.mapping.Property;
36 import org.hibernate.mapping.SimpleValue;
37
38
39
40
41 public class CopyIdentifierComponentSecondPass implements SecondPass {
42 private final String referencedEntityName;
43 private final Component component;
44 private final Mappings mappings;
45 private final Ejb3JoinColumn[] joinColumns;
46
47 public CopyIdentifierComponentSecondPass(
48 Component comp,
49 String referencedEntityName,
50 Ejb3JoinColumn[] joinColumns,
51 Mappings mappings) {
52 this.component = comp;
53 this.referencedEntityName = referencedEntityName;
54 this.mappings = mappings;
55 this.joinColumns = joinColumns;
56 }
57
58 @SuppressWarnings({ "unchecked" })
59 public void doSecondPass(Map persistentClasses) throws MappingException {
60 PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get( referencedEntityName );
61
62 if ( referencedPersistentClass == null ) {
63 throw new AnnotationException( "Unknown entity name: " + referencedEntityName );
64 }
65 if ( ! ( referencedPersistentClass.getIdentifier() instanceof Component ) ) {
66 throw new AssertionFailure(
67 "Unexpected identifier type on the referenced entity when mapping a @MapsId: "
68 + referencedEntityName
69 );
70 }
71 Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
72 Iterator<Property> properties = referencedComponent.getPropertyIterator();
73
74
75
76 boolean isExplicitReference = true;
77 Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String, Ejb3JoinColumn>(joinColumns.length);
78 for (Ejb3JoinColumn joinColumn : joinColumns) {
79 final String referencedColumnName = joinColumn.getReferencedColumn();
80 if ( referencedColumnName == null || BinderHelper.isEmptyAnnotationValue( referencedColumnName ) ) {
81 break;
82 }
83
84 columnByReferencedName.put( referencedColumnName.toLowerCase(), joinColumn );
85 }
86
87 int index = 0;
88 if ( columnByReferencedName.isEmpty() ) {
89 isExplicitReference = false;
90 for (Ejb3JoinColumn joinColumn : joinColumns) {
91 columnByReferencedName.put( "" + index, joinColumn );
92 index++;
93 }
94 index = 0;
95 }
96
97 while ( properties.hasNext() ) {
98 Property referencedProperty = properties.next();
99 if ( referencedProperty.isComposite() ) {
100 throw new AssertionFailure( "Unexpected nested component on the referenced entity when mapping a @MapsId: "
101 + referencedEntityName);
102 }
103 else {
104 Property property = new Property();
105 property.setName( referencedProperty.getName() );
106 property.setNodeName( referencedProperty.getNodeName() );
107
108
109 property.setPersistentClass( component.getOwner() );
110 property.setPropertyAccessorName( referencedProperty.getPropertyAccessorName() );
111 SimpleValue value = new SimpleValue( mappings, component.getTable() );
112 property.setValue( value );
113 final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue();
114 value.setTypeName( referencedValue.getTypeName() );
115 value.setTypeParameters( referencedValue.getTypeParameters() );
116 final Iterator<Column> columns = referencedValue.getColumnIterator();
117
118 if ( joinColumns[0].isNameDeferred() ) {
119 joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns(
120 referencedPersistentClass,
121 columns,
122 value);
123 }
124 else {
125
126 while ( columns.hasNext() ) {
127 Column column = columns.next();
128 final Ejb3JoinColumn joinColumn;
129 String logicalColumnName = null;
130 if ( isExplicitReference ) {
131 final String columnName = column.getName();
132 logicalColumnName = mappings.getLogicalColumnName( columnName, referencedPersistentClass.getTable() );
133
134 joinColumn = columnByReferencedName.get( logicalColumnName.toLowerCase() );
135 }
136 else {
137 joinColumn = columnByReferencedName.get( "" + index );
138 index++;
139 }
140 if ( joinColumn == null && ! joinColumns[0].isNameDeferred() ) {
141 throw new AnnotationException(
142 isExplicitReference ?
143 "Unable to find column reference in the @MapsId mapping: " + logicalColumnName :
144 "Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames: " + referencedEntityName
145 );
146 }
147 final String columnName = joinColumn == null || joinColumn.isNameDeferred() ? "tata_" + column.getName() : joinColumn
148 .getName();
149 value.addColumn( new Column( columnName ) );
150 column.setValue( value );
151 }
152 }
153 component.addProperty( property );
154 }
155 }
156 }
157 }