1 // $Id: FkSecondPass.java 11171 2007-02-08 03:40:51Z epbernard $
2 package org.hibernate.cfg;
3
4 import org.hibernate.AnnotationException;
5 import org.hibernate.AssertionFailure;
6 import org.hibernate.MappingException;
7 import org.hibernate.util.StringHelper;
8 import org.hibernate.cfg.annotations.TableBinder;
9 import org.hibernate.mapping.ManyToOne;
10 import org.hibernate.mapping.OneToOne;
11 import org.hibernate.mapping.PersistentClass;
12 import org.hibernate.mapping.ToOne;
13 import org.hibernate.mapping.Property;
14
15 /**
16 * Enable a proper set of the FK columns in respect with the id column order
17 * Allow the correct implementation of the default EJB3 values which needs both
18 * sides of the association to be resolved
19 *
20 * @author Emmanuel Bernard
21 */
22 public class FkSecondPass implements SecondPass {
23 private ToOne value;
24 private Ejb3JoinColumn[] columns;
25 private boolean unique;
26 private ExtendedMappings mappings;
27 private String path;
28 private String entityClassName;
29
30 FkSecondPass(
31 ToOne value, Ejb3JoinColumn[] columns, boolean unique, String entityClassName, String path, ExtendedMappings mappings
32 ) {
33 this.mappings = mappings;
34 this.value = value;
35 this.columns = columns;
36 this.unique = unique;
37 this.entityClassName = entityClassName;
38 this.path = entityClassName != null ? path.substring( entityClassName.length() + 1 ) : path;
39 }
40
41 public ToOne getValue() {
42 return value;
43 }
44
45 public boolean isInPrimaryKey() {
46 if (entityClassName == null) return false;
47 Property property = mappings.getClass( entityClassName ).getIdentifierProperty();
48 return property != null && path != null && path.startsWith( property.getName() );
49 }
50
51 public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
52 if ( value instanceof ManyToOne ) {
53 ManyToOne manyToOne = (ManyToOne) value;
54 PersistentClass ref = (PersistentClass) persistentClasses.get( manyToOne.getReferencedEntityName() );
55 if ( ref == null ) {
56 throw new AnnotationException(
57 "@OneToOne or @ManyToOne on "
58 + StringHelper.qualify(entityClassName, path)
59 + " references an unknown entity: "
60 + manyToOne.getReferencedEntityName()
61 );
62 }
63 BinderHelper.createSyntheticPropertyReference( columns, ref, null, manyToOne, false, mappings );
64 TableBinder.bindFk( ref, null, columns, manyToOne, unique, mappings );
65 /*
66 * HbmBinder does this only when property-ref != null, but IMO, it makes sense event if it is null
67 */
68 if ( ! manyToOne.isIgnoreNotFound() ) manyToOne.createPropertyRefConstraints( persistentClasses );
69 }
70 else if ( value instanceof OneToOne ) {
71 ( (OneToOne) value ).createForeignKey();
72 }
73 else {
74 throw new AssertionFailure( "FkSecondPass for a wrong value type: " + value.getClass().getName() );
75 }
76 }
77 }