下面列出了怎么用org.hibernate.AnnotationException的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void generateCreateStringsNoPkEntityTest() {
assertThatThrownBy(() -> {
Metadata metadata = new MetadataSources(this.registry)
.addAnnotatedClass(NoPkEntity.class)
.buildMetadata();
new SchemaExport()
.setOutputFile("unused")
.createOnly(EnumSet.of(TargetType.STDOUT, TargetType.SCRIPT), metadata);
})
.isInstanceOf(AnnotationException.class)
.hasMessage(
"No identifier specified for entity: "
+ "com.google.cloud.spanner.hibernate.SpannerTableExporterTests$NoPkEntity");
}
private void addConstraintToColumn(final String columnName ) {
Column column = table.getColumn(
new Column(
buildingContext.getMetadataCollector().getPhysicalColumnName( table, columnName )
)
);
if ( column == null ) {
throw new AnnotationException(
"@Index references a unknown column: " + columnName
);
}
if ( unique ) {
table.getOrCreateUniqueKey( indexName ).addColumn( column );
}
else {
table.getOrCreateIndex( indexName ).addColumn( column );
}
}
public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
/*
* Check table matches between the component and the columns
* if not, change the component table if no properties are set
* if a property is set already the core cannot support that
*/
if (columns != null) {
Table table = columns[0].getTable();
if ( !table.equals( component.getTable() ) ) {
if ( component.getPropertySpan() == 0 ) {
component.setTable( table );
}
else {
throw new AnnotationException(
"A component cannot hold properties split into 2 different tables: "
+ this.getPath()
);
}
}
}
addProperty( prop, declaringClass );
}
private static boolean isEntityClassType(XClass clazzToProcess, AnnotatedClassType classType) {
if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) //will be processed by their subentities
|| AnnotatedClassType.NONE.equals( classType ) //to be ignored
|| AnnotatedClassType.EMBEDDABLE.equals( classType ) //allow embeddable element declaration
) {
if ( AnnotatedClassType.NONE.equals( classType )
&& clazzToProcess.isAnnotationPresent( org.hibernate.annotations.Entity.class ) ) {
LOG.missingEntityAnnotation( clazzToProcess.getName() );
}
return false;
}
if ( !classType.equals( AnnotatedClassType.ENTITY ) ) {
throw new AnnotationException(
"Annotated class should have a @javax.persistence.Entity, @javax.persistence.Embeddable or @javax.persistence.EmbeddedSuperclass annotation: " + clazzToProcess
.getName()
);
}
return true;
}
private void getMapKeyClass(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
String nodeName = "map-key-class";
Element subelement = element != null ? element.element( nodeName ) : null;
if ( subelement != null ) {
String mapKeyClassName = subelement.attributeValue( "class" );
AnnotationDescriptor ad = new AnnotationDescriptor( MapKeyClass.class );
if ( StringHelper.isNotEmpty( mapKeyClassName ) ) {
Class clazz;
try {
clazz = classLoaderAccess.classForName(
XMLContext.buildSafeClassName( mapKeyClassName, defaults )
);
}
catch ( ClassLoadingException e ) {
throw new AnnotationException(
"Unable to find " + element.getPath() + " " + nodeName + ": " + mapKeyClassName, e
);
}
ad.setValue( "value", clazz );
}
annotationList.add( AnnotationFactory.create( ad ) );
}
}
private void getEnumerated(List<Annotation> annotationList, Element element) {
Element subElement = element != null ? element.element( "enumerated" ) : null;
if ( subElement != null ) {
AnnotationDescriptor ad = new AnnotationDescriptor( Enumerated.class );
String enumerated = subElement.getTextTrim();
if ( "ORDINAL".equalsIgnoreCase( enumerated ) ) {
ad.setValue( "value", EnumType.ORDINAL );
}
else if ( "STRING".equalsIgnoreCase( enumerated ) ) {
ad.setValue( "value", EnumType.STRING );
}
else if ( StringHelper.isNotEmpty( enumerated ) ) {
throw new AnnotationException( "Unknown EnumType: " + enumerated + ". " + SCHEMA_VALIDATION );
}
annotationList.add( AnnotationFactory.create( ad ) );
}
}
private void getTemporal(List<Annotation> annotationList, Element element) {
Element subElement = element != null ? element.element( "temporal" ) : null;
if ( subElement != null ) {
AnnotationDescriptor ad = new AnnotationDescriptor( Temporal.class );
String temporal = subElement.getTextTrim();
if ( "DATE".equalsIgnoreCase( temporal ) ) {
ad.setValue( "value", TemporalType.DATE );
}
else if ( "TIME".equalsIgnoreCase( temporal ) ) {
ad.setValue( "value", TemporalType.TIME );
}
else if ( "TIMESTAMP".equalsIgnoreCase( temporal ) ) {
ad.setValue( "value", TemporalType.TIMESTAMP );
}
else if ( StringHelper.isNotEmpty( temporal ) ) {
throw new AnnotationException( "Unknown TemporalType: " + temporal + ". " + SCHEMA_VALIDATION );
}
annotationList.add( AnnotationFactory.create( ad ) );
}
}
private void getAccessType(List<Annotation> annotationList, Element element) {
if ( element == null ) {
return;
}
String access = element.attributeValue( "access" );
if ( access != null ) {
AnnotationDescriptor ad = new AnnotationDescriptor( Access.class );
AccessType type;
try {
type = AccessType.valueOf( access );
}
catch ( IllegalArgumentException e ) {
throw new AnnotationException( access + " is not a valid access type. Check you xml confguration." );
}
if ( ( AccessType.PROPERTY.equals( type ) && this.element instanceof Method ) ||
( AccessType.FIELD.equals( type ) && this.element instanceof Field ) ) {
return;
}
ad.setValue( "value", type );
annotationList.add( AnnotationFactory.create( ad ) );
}
}
private Column getColumn(Element element, boolean isMandatory, Element current) {
//Element subelement = element != null ? element.element( "column" ) : null;
if ( element != null ) {
AnnotationDescriptor column = new AnnotationDescriptor( Column.class );
copyStringAttribute( column, element, "name", false );
copyBooleanAttribute( column, element, "unique" );
copyBooleanAttribute( column, element, "nullable" );
copyBooleanAttribute( column, element, "insertable" );
copyBooleanAttribute( column, element, "updatable" );
copyStringAttribute( column, element, "column-definition", false );
copyStringAttribute( column, element, "table", false );
copyIntegerAttribute( column, element, "length" );
copyIntegerAttribute( column, element, "precision" );
copyIntegerAttribute( column, element, "scale" );
return (Column) AnnotationFactory.create( column );
}
else {
if ( isMandatory ) {
throw new AnnotationException( current.getPath() + ".column is mandatory. " + SCHEMA_VALIDATION );
}
return null;
}
}
private static void bindNamedSubgraph(
XMLContext.Default defaults,
AnnotationDescriptor ann,
List<Element> subgraphNodes,
ClassLoaderAccess classLoaderAccess) {
List<NamedSubgraph> annSubgraphNodes = new ArrayList<>( );
for(Element subgraphNode : subgraphNodes){
AnnotationDescriptor annSubgraphNode = new AnnotationDescriptor( NamedSubgraph.class );
copyStringAttribute( annSubgraphNode, subgraphNode, "name", true );
String clazzName = subgraphNode.attributeValue( "class" );
Class clazz;
try {
clazz = classLoaderAccess.classForName(
XMLContext.buildSafeClassName( clazzName, defaults )
);
}
catch ( ClassLoadingException e ) {
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
}
annSubgraphNode.setValue( "type", clazz );
bindNamedAttributeNodes(subgraphNode, annSubgraphNode);
annSubgraphNodes.add( AnnotationFactory.create( annSubgraphNode ) );
}
ann.setValue( "subgraphs", annSubgraphNodes.toArray( new NamedSubgraph[annSubgraphNodes.size()] ) );
}
private static Class resolveClassReference(
String className,
XMLContext.Default defaults,
ClassLoaderAccess classLoaderAccess) {
if ( className == null ) {
throw new AnnotationException( "<entity-result> without entity-class. " + SCHEMA_VALIDATION );
}
try {
return classLoaderAccess.classForName(
XMLContext.buildSafeClassName( className, defaults )
);
}
catch ( ClassLoadingException e ) {
throw new AnnotationException( "Unable to find specified class: " + className, e );
}
}
private static void buildQueryHints(List<Element> elements, AnnotationDescriptor ann){
List<QueryHint> queryHints = new ArrayList<>( elements.size() );
for ( Element hint : elements ) {
AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
String value = hint.attributeValue( "name" );
if ( value == null ) {
throw new AnnotationException( "<hint> without name. " + SCHEMA_VALIDATION );
}
hintDescriptor.setValue( "name", value );
value = hint.attributeValue( "value" );
if ( value == null ) {
throw new AnnotationException( "<hint> without value. " + SCHEMA_VALIDATION );
}
hintDescriptor.setValue( "value", value );
queryHints.add( AnnotationFactory.create( hintDescriptor ) );
}
ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
}
/**
* Copy a string attribute from an XML element to an annotation descriptor. The name of the annotation attribute is
* explicitely given.
*
* @param annotation annotation where to copy to the attribute.
* @param element XML element from where to copy the attribute.
* @param annotationAttributeName name of the annotation attribute where to copy.
* @param attributeName name of the XML attribute to copy.
* @param mandatory whether the attribute is mandatory.
*/
private static void copyStringAttribute(
final AnnotationDescriptor annotation, final Element element,
final String annotationAttributeName, final String attributeName, boolean mandatory) {
String attribute = element.attributeValue( attributeName );
if ( attribute != null ) {
annotation.setValue( annotationAttributeName, attribute );
}
else {
if ( mandatory ) {
throw new AnnotationException(
element.getName() + "." + attributeName + " is mandatory in XML overriding. " + SCHEMA_VALIDATION
);
}
}
}
private static void copyIntegerAttribute(AnnotationDescriptor annotation, Element element, String attributeName) {
String attribute = element.attributeValue( attributeName );
if ( attribute != null ) {
String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
annotation.setValue( annotationAttributeName, attribute );
try {
int length = Integer.parseInt( attribute );
annotation.setValue( annotationAttributeName, length );
}
catch ( NumberFormatException e ) {
throw new AnnotationException(
element.getPath() + attributeName + " not parseable: " + attribute + " (" + SCHEMA_VALIDATION + ")"
);
}
}
}
/**
* Returns the value generation strategy for the given property, if any.
*/
private ValueGeneration getValueGenerationFromAnnotations(XProperty property) {
AnnotationValueGeneration<?> valueGeneration = null;
for ( Annotation annotation : property.getAnnotations() ) {
AnnotationValueGeneration<?> candidate = getValueGenerationFromAnnotation( property, annotation );
if ( candidate != null ) {
if ( valueGeneration != null ) {
throw new AnnotationException(
"Only one generator annotation is allowed:" + StringHelper.qualify(
holder.getPath(),
name
)
);
}
else {
valueGeneration = candidate;
}
}
}
return valueGeneration;
}
public boolean getBoolean(String query, String hintName) {
String value =(String) hintsMap.get( hintName );
if ( value == null ) {
return false;
}
if ( value.equalsIgnoreCase( "true" ) ) {
return true;
}
else if ( value.equalsIgnoreCase( "false" ) ) {
return false;
}
else {
throw new AnnotationException( "Not a boolean in hint: " + query + ":" + hintName );
}
}
public void bindDiscriminatorValue() {
if ( StringHelper.isEmpty( discriminatorValue ) ) {
Value discriminator = persistentClass.getDiscriminator();
if ( discriminator == null ) {
persistentClass.setDiscriminatorValue( name );
}
else if ( "character".equals( discriminator.getType().getName() ) ) {
throw new AnnotationException(
"Using default @DiscriminatorValue for a discriminator of type CHAR is not safe"
);
}
else if ( "integer".equals( discriminator.getType().getName() ) ) {
persistentClass.setDiscriminatorValue( String.valueOf( name.hashCode() ) );
}
else {
persistentClass.setDiscriminatorValue( name ); //Spec compliant
}
}
else {
//persistentClass.getDiscriminator()
persistentClass.setDiscriminatorValue( discriminatorValue );
}
}
public static void bindNamedStoredProcedureQuery(
NamedStoredProcedureQuery annotation,
MetadataBuildingContext context,
boolean isDefault) {
if ( annotation == null ) {
return;
}
if ( BinderHelper.isEmptyAnnotationValue( annotation.name() ) ) {
throw new AnnotationException( "A named query must have a name when used in class or package level" );
}
final NamedProcedureCallDefinition def = new NamedProcedureCallDefinition( annotation );
if (isDefault) {
context.getMetadataCollector().addDefaultNamedProcedureCallDefinition( def );
}
else {
context.getMetadataCollector().addNamedProcedureCallDefinition( def );
}
LOG.debugf( "Bound named stored procedure query : %s => %s", def.getRegisteredName(), def.getProcedureName() );
}
public Join getJoin() {
Join join = joins.get( explicitTableName );
if ( join == null ) {
// annotation binding seems to use logical and physical naming somewhat inconsistently...
final String physicalTableName = getBuildingContext().getMetadataCollector().getPhysicalTableName( explicitTableName );
if ( physicalTableName != null ) {
join = joins.get( physicalTableName );
}
}
if ( join == null ) {
throw new AnnotationException(
"Cannot find the expected secondary table: no "
+ explicitTableName + " available for " + propertyHolder.getClassName()
);
}
return join;
}
/**
* Recursively builds a list of FkSecondPass instances ready to be processed in this order.
* Checking all dependencies recursively seems quite expensive, but the original code just relied
* on some sort of table name sorting which failed in certain circumstances.
* <p/>
* See <tt>ANN-722</tt> and <tt>ANN-730</tt>
*
* @param orderedFkSecondPasses The list containing the <code>FkSecondPass<code> instances ready
* for processing.
* @param isADependencyOf Our lookup data structure to determine dependencies between tables
* @param startTable Table name to start recursive algorithm.
* @param currentTable The current table name used to check for 'new' dependencies.
*/
private void buildRecursiveOrderedFkSecondPasses(
List<FkSecondPass> orderedFkSecondPasses,
Map<String, Set<FkSecondPass>> isADependencyOf,
String startTable,
String currentTable) {
Set<FkSecondPass> dependencies = isADependencyOf.get( currentTable );
// bottom out
if ( dependencies == null || dependencies.size() == 0 ) {
return;
}
for ( FkSecondPass sp : dependencies ) {
String dependentTable = sp.getValue().getTable().getQualifiedTableName().render();
if ( dependentTable.compareTo( startTable ) == 0 ) {
throw new AnnotationException( "Foreign key circularity dependency involving the following tables: " + startTable + ", " + dependentTable );
}
buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, startTable, dependentTable );
if ( !orderedFkSecondPasses.contains( sp ) ) {
orderedFkSecondPasses.add( 0, sp );
}
}
}
/**
* 构造Hibernate的乐观锁
*/
private void handleVersion(Property prop, PersistentClass pclazz) {
if (!(pclazz instanceof RootClass)) {
throw new AnnotationException(
"Unable to define/override @Version on a subclass: "
+ pclazz.getEntityName());
}
RootClass root = (RootClass) pclazz;
root.setVersion(prop);
root.setDeclaredVersion(prop);
root.setOptimisticLockStyle(OptimisticLockStyle.VERSION);
}
@Test
public void generateCreateStringsEmptyEntityTest() {
assertThatThrownBy(() -> {
Metadata metadata = new MetadataSources(this.registry)
.addAnnotatedClass(EmptyEntity.class)
.buildMetadata();
new SchemaExport()
.setOutputFile("unused")
.createOnly(EnumSet.of(TargetType.STDOUT, TargetType.SCRIPT), metadata);
})
.isInstanceOf(AnnotationException.class)
.hasMessage(
"No identifier specified for entity: "
+ "com.google.cloud.spanner.hibernate.SpannerTableExporterTests$EmptyEntity");
}
public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
if ( value instanceof ManyToOne ) {
ManyToOne manyToOne = (ManyToOne) value;
PersistentClass ref = (PersistentClass) persistentClasses.get( manyToOne.getReferencedEntityName() );
if ( ref == null ) {
throw new AnnotationException(
"@OneToOne or @ManyToOne on "
+ StringHelper.qualify( entityClassName, path )
+ " references an unknown entity: "
+ manyToOne.getReferencedEntityName()
);
}
manyToOne.setPropertyName( path );
BinderHelper.createSyntheticPropertyReference( columns, ref, null, manyToOne, false, buildingContext );
TableBinder.bindFk( ref, null, columns, manyToOne, unique, buildingContext );
/*
* HbmMetadataSourceProcessorImpl does this only when property-ref != null, but IMO, it makes sense event if it is null
*/
if ( !manyToOne.isIgnoreNotFound() ) manyToOne.createPropertyRefConstraints( persistentClasses );
}
else if ( value instanceof OneToOne ) {
value.createForeignKey();
}
else {
throw new AssertionFailure( "FkSecondPass for a wrong value type: " + value.getClass().getName() );
}
}
private void assertTypesAreResolvable() {
for ( XProperty xProperty : persistentAttributeMap.values() ) {
if ( !xProperty.isTypeResolved() && !discoverTypeWithoutReflection( xProperty ) ) {
String msg = "Property " + StringHelper.qualify( xClass.getName(), xProperty.getName() ) +
" has an unbound type and no explicit target entity. Resolve this Generic usage issue" +
" or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type";
throw new AnnotationException( msg );
}
}
}
private static boolean discoverTypeWithoutReflection(XProperty p) {
if ( p.isAnnotationPresent( OneToOne.class ) && !p.getAnnotation( OneToOne.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( OneToMany.class ) && !p.getAnnotation( OneToMany.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToOne.class ) && !p.getAnnotation( ManyToOne.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToMany.class ) && !p.getAnnotation( ManyToMany.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToAny.class ) ) {
if ( !p.isCollection() && !p.isArray() ) {
throw new AnnotationException( "@ManyToAny used on a non collection non array property: " + p.getName() );
}
return true;
}
else if ( p.isAnnotationPresent( Type.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( Target.class ) ) {
return true;
}
return false;
}
Ejb3JoinColumn[] buildDefaultJoinColumnsForXToOne(XProperty property, PropertyData inferredData) {
Ejb3JoinColumn[] joinColumns;
JoinTable joinTableAnn = propertyHolder.getJoinTable( property );
if ( joinTableAnn != null ) {
joinColumns = Ejb3JoinColumn.buildJoinColumns(
joinTableAnn.inverseJoinColumns(),
null,
entityBinder.getSecondaryTables(),
propertyHolder,
inferredData.getPropertyName(),
buildingContext
);
if ( StringHelper.isEmpty( joinTableAnn.name() ) ) {
throw new AnnotationException(
"JoinTable.name() on a @ToOne association has to be explicit: "
+ BinderHelper.getPath( propertyHolder, inferredData )
);
}
}
else {
OneToOne oneToOneAnn = property.getAnnotation( OneToOne.class );
String mappedBy = oneToOneAnn != null
? oneToOneAnn.mappedBy()
: null;
joinColumns = Ejb3JoinColumn.buildJoinColumns(
null,
mappedBy,
entityBinder.getSecondaryTables(),
propertyHolder,
inferredData.getPropertyName(),
buildingContext
);
}
return joinColumns;
}
public void doSecondPass(Map persistentClasses) throws MappingException {
PersistentClass referencedEntity = (PersistentClass) persistentClasses.get( referencedEntityName );
if ( referencedEntity == null ) {
throw new AnnotationException(
"Unknown entity name: " + referencedEntityName
);
}
TableBinder.linkJoinColumnWithValueOverridingNameIfImplicit(
referencedEntity,
referencedEntity.getKey().getColumnIterator(),
columns,
value);
}
private static AttributeConverter instantiateAttributeConverter(Class<? extends AttributeConverter> attributeConverterClass) {
try {
return attributeConverterClass.newInstance();
}
catch (Exception e) {
throw new AnnotationException(
"Unable to instantiate AttributeConverter [" + attributeConverterClass.getName() + "]",
e
);
}
}
public static void checkIfJoinColumn(Object columns, PropertyHolder holder, PropertyData property) {
if ( !( columns instanceof Ejb3JoinColumn[] ) ) {
throw new AnnotationException(
"@Column cannot be used on an association property: "
+ holder.getEntityName()
+ "."
+ property.getPropertyName()
);
}
}
protected ConverterDescriptor makeAttributeConverterDescriptor(AttributeConversionInfo conversion) {
try {
return new ClassBasedConverterDescriptor(
conversion.getConverterClass(),
false,
context.getBootstrapContext().getClassmateContext()
);
}
catch (Exception e) {
throw new AnnotationException( "Unable to create AttributeConverter instance", e );
}
}