Loading multiple annotated classes in Hibernate - java

I am using hibernate annotations and for that in the hibernate.cfg.xml i need to add annotated classes like this <mapping class="p.Customer" /> here p is the package name and Customer is the annotated bean.
Suppose i have 20 such kind of annotated classes, it means I have to write 20 mapping lines for that class.In Spring there is a property packageToScan that can be used to register/load all hibernate annotated classes in the specified package.
Since I am not using Spring, can we have the same functionality in Hibernate?
Also I found one tag in hibernate.cfg.xml <mapping package="" /> at first I thought this will do the job for me, but it didn't work. I didn't get what is the use of this property.

The magic of annotations parsing is done when creating session factory. Hibernate can do it without spring. Spring actually just wraps the hibernate functionality.
Please take a look on this article: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-overview
They show how to register classes in session factory, so the annotations are used. They indeed do not provide functionality of scanning but you can either implement it yourself or better use other package. I used "reflections" package for similar purpose. I mean I scanned my classpath to locate classes according to my criteria using reflections package. I did not use it for hibernate but I am sure it is possible.
Here is the reference that can help you.
http://code.google.com/p/reflections/

1,refer :
How to get all classes names in a package?
2,extend org.hibernate.cfg.Configuration
`
package com.hw.configuration;
import com.hw.util.ClassFinder;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import java.util.List;
/**
* Created by whuanghkl on 17/5/31.
*/
public class WildCardConfiguration extends Configuration {
#Override
public Configuration addPackage(String packageName) throws MappingException {
List<Class<?>> classes = ClassFinder.find(packageName);
int size=classes.size();
for (int i=0;i<size;i++){
super.addAnnotatedClass(classes.get(i));
}
return this;
}
}
`
3,
`
new SchemaExport(new
WildCardConfiguration().configure()).create(true, false);
`

Related

Find class marked with annotation of a specific value

I'm using this Java Reflections API that I'm finding quite convenient so far:
https://github.com/ronmamo/reflections
Find all classes marked with a specific annotation is dead easy, however, I can't figure out how to add a filter in the scanner to retrieve classes that have that annotation configured in a certain way.
For example, if I have three classes:
#Important(level="high")
public class HighlyImportant { }
#Important(level="medium")
public class ModeratelyImportant { }
#Important(level="low")
public class NotSoImportant { }
I can get all three classes by scanning for the #Important annotation, but how do I restrict that to only #Important(level=high) ?
Thanks

Can't autowire a component into a utility class

I'm having a problem autowiring a component into a utility class. The utility class initially had static methods in it, but then I just made them instance methods.
I defined the utility class with #Component and within the class put in
class MyUtilityClass {
#Autowired
ExistingComponent existingComponent
...
}
The package the utility class is in is under the specified parent directory for #ComponentScan, where value="top-level-directory" that also contains the packages for all the other autowired components.
To get the utility class to run I had to pass the ExistingComponent into a constructor for the utility class.
Using Spring 4.1.6.
This is probably something basic, but it's not clicking. What am I missing here?
Thanks.
UPDATE 1
The class that is calling the utility class looks like the following:
class UsingClass {
#Autowired
MyUtilityClass myUtilityClass
...
def method1() {
String variable1 = "some data"
myUtilityClass.utilityMethod(variable1)
...
}
}
Originally I had the internal utility method as static and tried to use the utility class without autowiring it.
Do you have this somewhere within your beans XML configuration files?
<context:component-scan base-package="com.your.package" />
The base-package indicates where your components are stored.
This allows Spring to scan the package so that it can find the beans annotated with #Component.
This is explained in more depth here.

Where to place a private method that shared by multiple Spring java config file?

I have several Spring Java config classes and they have same private method. Should I create the private method in each Java config class or do I have other options to avoid listing duplicate method. By the way, I have a CommonConfig.java class imported by all other config classes. Can I make the private method and place it inside CommonConfig.java?
By the way, all other Spring Java Config classes import CommonConfig like bellow.
#Import({ CommonConfig.class, })
You can initialize the method in CommonConfig.java class, do not make it private else the extending classes won't be able to use it.
If the implementation of that method is different as per the classes you can make an interface & declare that method in that.

Why is package-info.java useful?

When I run CheckStyle over my Java project it says Missing package-info.java file. for some classes, but not all of them. I can't really figure out why this message appears only sometimes. Furthermore my project runs perfectly fine without the package-info.java.
What does the package-info.java do? Do I really need it for my Java projects?
It is used to generate javadocs for a package.
/**
* Domain classes used to produce .....
* <p>
* These classes contain the ......
* </p>
*
* #since 1.0
* #author somebody
* #version 1.0
*/
package com.domain;
Will generate package info for com.domain package:
Example result: https://docs.oracle.com/javase/7/docs/api/java/awt/package-summary.html
Annotations
Another good reason to use package-info.java is to add default annotations for use by FindBugs. For instance, if you put this in your package-info file:
#DefaultAnnotation(NonNull.class)
package com.my.package;
then when findbugs runs on the code in that package, all methods and fields are assumed to be non-null unless you annotate them with #CheckForNull. This is much nicer and more foolproof than requiring developers to add #NonNull annotations to each method and field.
Not only some findbugs annotations, but a lot of java annotations in common libraries have the java.lang.annotation.ElementType.PACKAGE type as one of the possible values of their own java.lang.annotation.Target annotation, e.g.:
com.google.gwt.core.client.js.JsNamespace
com.querydsl.core.annotations.Config
com.sun.xml.bind.XmlAccessorFactory
groovy.transform.BaseScript
java.lang.Deprecated
javax.annotation.Generated
javax.xml.bind.annotation.XmlAccessorOrder
org.hibernate.annotations.TypeDef
net.sf.ehcache.pool.sizeof.annotations.IgnoreSizeOf
org.apache.hive.common.HiveVersionAnnotation
org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeAction
org.codehaus.commons.nullanalysis.NotNullByDefault
org.eclipse.persistence.oxm.annotations.XmlNameTransformer
org.glassfish.jersey.Beta
org.jgroups.annotations.Experimental
and much more.
This package-info.java file would be the file, where you can place such annotations (along with the javadoc).
A package-info.java file allows adding javadoc to document a whole package. See http://docs.oracle.com/javase/7/docs/api/java/applet/package-summary.html for example.
If you don't care about missing package documentation, then ignore the warning or disable the JavadocPackage check.
The package-info.java is a Java file that can be added to any Java source package. It is used to provide info at a "package" level as per its name.
It contains documentation and annotations used in the package.
javadoc example is already provided in the answer, the below part explains how it works incase of annotations.
For example, in the below file it is used to "substitute" the occurance of joda.time.DateTime with org.jadira.usertype.dateandtime.joda.PersistentDateTime
#TypeDefs({
#TypeDef(name = "PersistentDateTime", typeClass = PersistentDateTime.class, defaultForType=DateTime.class)})
package xyz.abc;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.jadira.usertype.dateandtime.joda.PersistentDateTime;
import org.joda.time.DateTime;
There are a number of annotations available with which can be used to perform different things at "package" level. It can be found at https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/annotations/package-summary.html

System wide adapter in Jersey?

I'm trying configure a "system wide" custom javax.xml.bind.annotation.adapters.XmlAdapter for the java.util.Locale type in Jersey. It's easy enough to use #XmlJavaTypeAdapter on classes I control but that's not always the case (3rd party code that I can't annotate).
It seems like it would be a pretty common problem but I can't find any good examples or doco on how to handle it.
So, is it possible?
Thanks!
I can see three possible options:
Register the converter with the marshaller with setAdapter(). You can have a static builder function which adds all your 'system level' type adapters to all marshallers which you use in your application. It all depends on your definition of 'system level'
Use a delegate
Do some fancy bytecode trickery to add the annotations to existing class files.
My advice would be to use approach 1, which is simple and straightforward.
If you need to annotate classes you can't modify, you could always use the externalized metadata feature of EclipseLink JAXB (MOXy).
The metadata file would look something like:
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
<java-types>
<java-type name="java.util.Locale">
<xml-java-type-adapter value="some.package.YourAdapter"/>
</java-type>
</java-types>
</xml-bindings>
To you EclipseLink MOXy you need to add a jaxb.properties file in with your model classes with the following entry:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
You may also want to look at JAXBIntroductions project which is intended for similar purpose. The annotation configuration is kept in a file, without requiring modification to source code. It does work nicely with Jersey, by implementing a JAX-RS provider. You can check out my blog entry which explains this in detail with an example. Here is a simple JAXBContextResolver provide for JAXBIntroductions that can be used in your Jersey application.
import com.sun.xml.bind.api.JAXBRIContext;
import org.jboss.jaxb.intros.IntroductionsAnnotationReader;
import org.jboss.jaxb.intros.IntroductionsConfigParser;
import org.jboss.jaxb.intros.configmodel.JaxbIntros;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import java.util.*;
#Provider
public class JAXBContextResolverForJAXBIntroductions implements ContextResolver<JAXBContext> {
private final JAXBContext context;
private final Set<Class> types;
private final Class[] cTypes = {Customer.class};
public JAXBContextResolverForJAXBIntroductions() throws Exception {
this.types = new HashSet(Arrays.asList(cTypes));
JaxbIntros config = IntroductionsConfigParser.parseConfig(this.getClass().getResourceAsStream("/intro-config.xml"));
IntroductionsAnnotationReader reader = new IntroductionsAnnotationReader(config);
Map<String, Object> jaxbConfig = new HashMap<String, Object>();
jaxbConfig.put(JAXBRIContext.ANNOTATION_READER, reader);
this.context = JAXBContext.newInstance(cTypes, jaxbConfig);
}
public JAXBContext getContext(Class<?> objectType) {
return (types.contains(objectType)) ? context : null;
}
}

Categories