/** * Build a normal attribute. * * @param ownerType The descriptor of the attribute owner (aka declarer). * @param property The Hibernate property descriptor for the attribute * @param <X> The type of the owner * @param <Y> The attribute type * @return The built attribute descriptor or null if the attribute is not part of the JPA 2 model * (eg backrefs) */ @SuppressWarnings({"unchecked"}) public <X, Y> AttributeImplementor<X, Y> buildAttribute( AbstractManagedType<X> ownerType, Property property) { if (property.isSynthetic()) { // hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel. LOG.tracef( "Skipping synthetic property %s(%s)", ownerType.getJavaType().getName(), property.getName()); return null; } LOG.trace( "Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]"); final AttributeContext<X> attributeContext = wrap(ownerType, property); final AttributeMetadata<X, Y> attributeMetadata = determineAttributeMetadata(attributeContext, NORMAL_MEMBER_RESOLVER); if (attributeMetadata == null) { return null; } if (attributeMetadata.isPlural()) { return buildPluralAttribute((PluralAttributeMetadata) attributeMetadata); } final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata; final Type<Y> metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext()); return new SingularAttributeImpl<X, Y>( attributeMetadata.getName(), attributeMetadata.getJavaType(), ownerType, attributeMetadata.getMember(), false, false, property.isOptional(), metaModelType, attributeMetadata.getPersistentAttributeType()); }
/** * Build the version attribute descriptor * * @param ownerType The descriptor of the attribute owner (aka declarer). * @param property The Hibernate property descriptor for the version attribute * @param <X> The type of the owner * @param <Y> The attribute type * @return The built attribute descriptor */ @SuppressWarnings({"unchecked"}) public <X, Y> SingularAttributeImpl<X, Y> buildVersionAttribute( AbstractIdentifiableType<X> ownerType, Property property) { LOG.trace( "Building version attribute [ownerType.getJavaType().getName()" + "." + "property.getName()]"); final AttributeContext<X> attributeContext = wrap(ownerType, property); final SingularAttributeMetadata<X, Y> attributeMetadata = (SingularAttributeMetadata<X, Y>) determineAttributeMetadata(attributeContext, VERSION_MEMBER_RESOLVER); final Type<Y> metaModelType = getMetaModelType(attributeMetadata.getValueContext()); return new SingularAttributeImpl.Version( property.getName(), attributeMetadata.getJavaType(), ownerType, attributeMetadata.getMember(), metaModelType, attributeMetadata.getPersistentAttributeType()); }
private static Document loadURL(URL configURL, EntityResolver resolver) throws Exception { /* * try and parse the document: * - try and validate the document with persistence_2_0.xsd * - if it fails because of the version attribute mismatch, try and validate the document with persistence_1_0.xsd */ InputStream is = null; if (configURL != null) { URLConnection conn = configURL.openConnection(); conn.setUseCaches(false); // avoid JAR locking on Windows and Tomcat is = conn.getInputStream(); } if (is == null) { throw new IOException( "Failed to obtain InputStream while reading persistence.xml file: " + configURL); } DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setNamespaceAware(true); final Schema v2Schema = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema(new StreamSource(getStreamFromClasspath("persistence_2_0.xsd"))); final Validator v2Validator = v2Schema.newValidator(); final Schema v1Schema = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema(new StreamSource(getStreamFromClasspath("persistence_1_0.xsd"))); final Validator v1Validator = v1Schema.newValidator(); InputSource source = new InputSource(is); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); docBuilder.setEntityResolver(resolver); List<SAXParseException> errors = new ArrayList<SAXParseException>(); Document doc = null; // first sparse document and collect syntaxic errors try { doc = docBuilder.parse(source); } catch (SAXParseException e) { errors.add(e); } if (errors.size() == 0) { v2Validator.setErrorHandler(new ErrorLogger(errors)); LOG.trace("Validate with persistence_2_0.xsd schema on file " + configURL); v2Validator.validate(new DOMSource(doc)); boolean isV1Schema = false; if (errors.size() != 0) { // v2 fails, it could be because the file is v1. LOG.trace("Found error with persistence_2_0.xsd schema on file " + configURL); SAXParseException exception = errors.get(0); final String errorMessage = exception.getMessage(); // is it a validation error due to a v1 schema validated by a v2 isV1Schema = errorMessage.contains("1.0") && errorMessage.contains("2.0") && errorMessage.contains("version"); } if (isV1Schema) { LOG.trace("Validate with persistence_1_0.xsd schema on file " + configURL); errors.clear(); v1Validator.setErrorHandler(new ErrorLogger(errors)); v1Validator.validate(new DOMSource(doc)); } } if (errors.size() != 0) { // report all errors in the exception StringBuilder errorMessage = new StringBuilder(); for (SAXParseException error : errors) { errorMessage .append("Error parsing XML (line") .append(error.getLineNumber()) .append(" : column ") .append(error.getColumnNumber()) .append("): ") .append(error.getMessage()) .append("\n"); } throw new PersistenceException("Invalid persistence.xml.\n" + errorMessage.toString()); } return doc; }
private static PersistenceMetadata parsePersistenceUnit(Element top) throws Exception { PersistenceMetadata metadata = new PersistenceMetadata(); String puName = top.getAttribute("name"); if (StringHelper.isNotEmpty(puName)) { LOG.trace("Persistent Unit name from persistence.xml: " + puName); metadata.setName(puName); } NodeList children = top.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) children.item(i); String tag = element.getTagName(); // if ( tag.equals( "name" ) ) { // String puName = XmlHelper.getElementContent( element ); // log.trace( "FOUND PU NAME: " + puName ); // metadata.setName( puName ); // } // else if (tag.equals("non-jta-data-source")) { metadata.setNonJtaDatasource(XmlHelper.getElementContent(element)); } else if (tag.equals("jta-data-source")) { metadata.setJtaDatasource(XmlHelper.getElementContent(element)); } else if (tag.equals("provider")) { metadata.setProvider(XmlHelper.getElementContent(element)); } else if (tag.equals("class")) { metadata.getClasses().add(XmlHelper.getElementContent(element)); } else if (tag.equals("mapping-file")) { metadata.getMappingFiles().add(XmlHelper.getElementContent(element)); } else if (tag.equals("jar-file")) { metadata.getJarFiles().add(XmlHelper.getElementContent(element)); } else if (tag.equals("exclude-unlisted-classes")) { metadata.setExcludeUnlistedClasses(true); } else if (tag.equals("delimited-identifiers")) { metadata.setUseQuotedIdentifiers(true); } else if (tag.equals("validation-mode")) { metadata.setValidationMode(XmlHelper.getElementContent(element)); } else if (tag.equals("shared-cache-mode")) { metadata.setSharedCacheMode(XmlHelper.getElementContent(element)); } else if (tag.equals("properties")) { NodeList props = element.getChildNodes(); for (int j = 0; j < props.getLength(); j++) { if (props.item(j).getNodeType() == Node.ELEMENT_NODE) { Element propElement = (Element) props.item(j); if (!"property".equals(propElement.getTagName())) continue; String propName = propElement.getAttribute("name").trim(); String propValue = propElement.getAttribute("value").trim(); if (StringHelper.isEmpty(propValue)) { // fall back to the natural (Hibernate) way of description propValue = XmlHelper.getElementContent(propElement, ""); } metadata.getProps().put(propName, propValue); } } } } } PersistenceUnitTransactionType transactionType = getTransactionType(top.getAttribute("transaction-type")); if (transactionType != null) metadata.setTransactionType(transactionType); return metadata; }
/** * Here is most of the nuts and bolts of this factory, where we interpret the known JPA metadata * against the known Hibernate metadata and build a descriptor for the attribute. * * @param attributeContext The attribute to be described * @param memberResolver Strategy for how to resolve the member defining the attribute. * @param <X> The owner type * @param <Y> The attribute type * @return The attribute description */ @SuppressWarnings({"unchecked"}) private <X, Y> AttributeMetadata<X, Y> determineAttributeMetadata( AttributeContext<X> attributeContext, MemberResolver memberResolver) { LOG.trace( "Starting attribute metadata determination [" + attributeContext.getPropertyMapping().getName() + "]"); final Member member = memberResolver.resolveMember(attributeContext); LOG.trace(" Determined member [" + member + "]"); final Value value = attributeContext.getPropertyMapping().getValue(); final org.hibernate.type.Type type = value.getType(); LOG.trace( " Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]"); if (type.isAnyType()) { // ANY mappings are currently not supported in the JPA metamodel; see HHH-6589 if (context.isIgnoreUnsupported()) { return null; } else { throw new UnsupportedOperationException("ANY not supported"); } } else if (type.isAssociationType()) { // collection or entity if (type.isEntityType()) { // entity return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, determineSingularAssociationAttributeType(member)); } // collection if (value instanceof Collection) { final Collection collValue = (Collection) value; final Value elementValue = collValue.getElement(); final org.hibernate.type.Type elementType = elementValue.getType(); // First, determine the type of the elements and use that to help determine the // collection type) final Attribute.PersistentAttributeType elementPersistentAttributeType; final Attribute.PersistentAttributeType persistentAttributeType; if (elementType.isAnyType()) { throw new UnsupportedOperationException("collection of any not supported yet"); } final boolean isManyToMany = isManyToMany(member); if (elementValue instanceof Component) { elementPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED; persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION; } else if (elementType.isAssociationType()) { elementPersistentAttributeType = isManyToMany ? Attribute.PersistentAttributeType.MANY_TO_MANY : Attribute.PersistentAttributeType.ONE_TO_MANY; persistentAttributeType = elementPersistentAttributeType; } else { elementPersistentAttributeType = Attribute.PersistentAttributeType.BASIC; persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION; } final Attribute.PersistentAttributeType keyPersistentAttributeType; // Finally, we determine the type of the map key (if needed) if (value instanceof Map) { final Value keyValue = ((Map) value).getIndex(); final org.hibernate.type.Type keyType = keyValue.getType(); if (keyType.isAnyType()) throw new UnsupportedOperationException("collection of any not supported yet"); if (keyValue instanceof Component) keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED; else if (keyType.isAssociationType()) keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE; else keyPersistentAttributeType = Attribute.PersistentAttributeType.BASIC; } else keyPersistentAttributeType = null; return new PluralAttributeMetadataImpl( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, persistentAttributeType, elementPersistentAttributeType, keyPersistentAttributeType); } else if (value instanceof OneToMany) { // TODO : is this even possible??? Really OneToMany should be describing the // element value within a o.h.mapping.Collection (see logic branch above) throw new IllegalArgumentException("HUH???"); // final boolean isManyToMany = isManyToMany( member ); // //one to many with FK => entity // return new PluralAttributeMetadataImpl( // attributeContext.getPropertyMapping(), // attributeContext.getOwnerType(), // member, // isManyToMany // ? Attribute.PersistentAttributeType.MANY_TO_MANY // : Attribute.PersistentAttributeType.ONE_TO_MANY // value, // AttributeContext.TypeStatus.ENTITY, // Attribute.PersistentAttributeType.ONE_TO_MANY, // null, null, null // ); } } else if (attributeContext.getPropertyMapping().isComposite()) { // component return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.EMBEDDED); } else { // basic type return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.BASIC); } throw new UnsupportedOperationException( "oops, we are missing something: " + attributeContext.getPropertyMapping()); }
@Override @SuppressWarnings({"deprecation"}) public TypedQuery<X> setHint(String hintName, Object value) { boolean skipped = false; try { if (HINT_TIMEOUT.equals(hintName)) { applyTimeout(ConfigurationHelper.getInteger(value)); } else if (SPEC_HINT_TIMEOUT.equals(hintName)) { // convert milliseconds to seconds int timeout = (int) Math.round(ConfigurationHelper.getInteger(value).doubleValue() / 1000.0); applyTimeout(timeout); } else if (AvailableSettings.LOCK_TIMEOUT.equals(hintName)) { applyLockTimeout(ConfigurationHelper.getInteger(value)); } else if (HINT_COMMENT.equals(hintName)) { applyComment((String) value); } else if (HINT_FETCH_SIZE.equals(hintName)) { applyFetchSize(ConfigurationHelper.getInteger(value)); } else if (HINT_CACHEABLE.equals(hintName)) { applyCacheable(ConfigurationHelper.getBoolean(value)); } else if (HINT_CACHE_REGION.equals(hintName)) { applyCacheRegion((String) value); } else if (HINT_READONLY.equals(hintName)) { applyReadOnly(ConfigurationHelper.getBoolean(value)); } else if (HINT_CACHE_MODE.equals(hintName)) { applyCacheMode(ConfigurationHelper.getCacheMode(value)); } else if (HINT_FLUSH_MODE.equals(hintName)) { applyFlushMode(ConfigurationHelper.getFlushMode(value)); } else if (AvailableSettings.SHARED_CACHE_RETRIEVE_MODE.equals(hintName)) { final CacheRetrieveMode retrieveMode = (CacheRetrieveMode) value; CacheStoreMode storeMode = hints != null ? (CacheStoreMode) hints.get(AvailableSettings.SHARED_CACHE_STORE_MODE) : null; if (storeMode == null) { storeMode = (CacheStoreMode) entityManager.getProperties().get(AvailableSettings.SHARED_CACHE_STORE_MODE); } applyCacheMode(CacheModeHelper.interpretCacheMode(storeMode, retrieveMode)); } else if (AvailableSettings.SHARED_CACHE_STORE_MODE.equals(hintName)) { final CacheStoreMode storeMode = (CacheStoreMode) value; CacheRetrieveMode retrieveMode = hints != null ? (CacheRetrieveMode) hints.get(AvailableSettings.SHARED_CACHE_RETRIEVE_MODE) : null; if (retrieveMode == null) { retrieveMode = (CacheRetrieveMode) entityManager.getProperties().get(AvailableSettings.SHARED_CACHE_RETRIEVE_MODE); } applyCacheMode(CacheModeHelper.interpretCacheMode(storeMode, retrieveMode)); } else if (hintName.startsWith(AvailableSettings.ALIAS_SPECIFIC_LOCK_MODE)) { if (!canApplyLockModes()) { skipped = true; } else { // extract the alias final String alias = hintName.substring(AvailableSettings.ALIAS_SPECIFIC_LOCK_MODE.length() + 1); // determine the LockMode try { final LockMode lockMode = LockModeTypeHelper.interpretLockMode(value); applyAliasSpecificLockMode(alias, lockMode); } catch (Exception e) { LOG.unableToDetermineLockModeValue(hintName, value); skipped = true; } } } else { skipped = true; LOG.ignoringUnrecognizedQueryHint(hintName); } } catch (ClassCastException e) { throw new IllegalArgumentException("Value for hint"); } if (!skipped) { if (hints == null) { hints = new HashMap<String, Object>(); } hints.put(hintName, value); } return this; }