Go to http://www.springsource.org/download
There, you'll find something like "GET THE LATEST SPRING RELEASES HERE". Choose the latest one unless you know better. Click "Download". This gets you down a big zip containing loads of JARs with names like:
Depending on what you're doing, you'll need one or more of these.
It's challenging to find stuff. For example, @Repository is in org.springframework.context-3.1.0.RC2.jar while @Transactional is in org.springframework.transaction-3.1.0.RC2.jar.
Look for sample code. The Spring documentation will prat on and on using annotations without telling you where to get them. Sample code, on the other hand, will probably contain import statements that reveal, for instance, that @Repository is in org.springframework.stereotype.Repository.
Then, you can Google for "org.springframework.stereotype jar" and find out where it is (in Spring "context"; see first section above, this would be in org.springframeword.context-3.1.0.RC2.jar).
These are annotations, not all necessarily from Spring, but ones that I'm using in work primarily motivated by moving to adopt a subset of Spring framework.
{ ... // in AccountWebService.java: private static AccountManager accountManager = ServiceLocator.get( AccountManager.class ); // in AccountManager.java: @Implementor(AccountManager.class) public class AccountManager { ...
import org.springframework.stereotype.Repository
See http://onjavahell.blogspot.com/2009/04/dependencies-injection-with-spring.html. See also http://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/. For discussion of whether or not to continue to use Hibernate templates with Spring, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/orm.html#orm-hibernate-straight and also, this discussion.
import org.springframework.transaction.annotation.Transactional
See http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html#transaction-declarative-annotations. See also http://static.springsource.org/spring/docs/3.1.0.RELEASE/reference/html/transaction.html#transaction-declarative-annotations.
import org.springframework.stereotype.Service
In the example below, the AccountManager's accountRepository member variable (or "field") is autowired to AccountRepository. What "bean" ('cause Spring likes the word "bean" historically and over-uses it) is wired is indicated by the argument to @Service. This said, the latter annotation could go missing as long as a) @Autowired is used on the member instead of the constructor (since the class in question is perfectly obvious) and b) there are no other columns ("fields") being autowired.
@Service( "accountManager" ) public class AccountManager { @Autowired AccountRepository accountRepository; public void setAccountDao( AccountRepository accountRepository ) { this.accountRepository = accountRepository; } ...
Religiously, constructor auto-wiring appears preferred. Concretely, there are apparently advantages for creating mocks in testing and constructor-autowiring will fail earlier, perhaps during compilation, when something's wrong.
@Service( "accountManager" ) public class AccountManager { AccountRepository accountRepository; @Autowired public AccountManager( AccountRepository accountRepository ) { this.accountRepository = accountRepository; } ...
However, this can be over-done creating a nightmare of interdependencies and a "Spring meltdown" that is what people who only want "light" Spring advantages hate most about the framework.
import org.springframework.beans.factory.annotation.Autowired
Important note on the persistence bean annotations that follow:
Annotations from javax.persistence are found in JARs such as (Apache) openjpa-all-2.0.0-M3.jar, (Hibernate) hibernate-jpa-2.0-api-1.0.0.Final.jar and, of course, in the Glassfish JEE distribution.
In documentation, member variables of the bean class are often referred to as "fields" while the corresponding getter methods are called "properties".
@Entity @Table( name = "account" ) public class Account implements Serializable { private static final long serialVersionUID = 5909795088113044065L; ...
import javax.persistence.Entity
import javax.persistence.Table
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not insert: \ [com.mkyong.entity.Account]; SQL [insert into mkyong.account (name, phone) values (?, ?)]; \ constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: \ could not insert: [com.mkyong.entity.Account] Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.mkyong.entity.Account] Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: \ Duplicate entry 'Jack the Ripper' for key 'UNI_NAME'
@Entity @Table( name = "account", catalog = "mkyong", uniqueConstraints = { @UniqueConstraint( columnNames = "name" ), @UniqueConstraint( columnNames = "phone" ) } ) public class Account implements Serializable { private static final long serialVersionUID = 797886879568152606L; ...
import javax.persistence.UniqueConstraint
It appears that there is no annotation for defaulting the value upon creation. It's possible to initialize the member variable, however.
public Account { ... private boolean loggedin = false; ... @Column( name = "loggedin", nullable = false, updatable = true ) public boolean getLoggedin() { return this.loggedin; } public void setLoggedin( boolean loggedin ) { this.loggedin = loggedin; } ...
import javax.persistence.Column
import javax.persistence.Id
{ ... @Id @Column(name = "id") @GeneratedValue( strategy = GenerationType.AUTO ) public Integer getId() { return id; } public void setId( Integer id ) { this.id = id; } ...
import javax.persistence.GeneratedValue import static javax.persistence.GenerationType.IDENTITY;
Note: You cannot use the @Column annotation on a column/field marked with @OneToOne.
import javax.persistence.OneToMany
import javax.persistence.JoinColumn
There's some secret thing that has, so far, defied my understanding, but which works for setting up DAOs (or here, I'm calling it a "repository" since that's what my work colleagues are liking).
Go looking for method getHibernateTemplate() in Spring or Hibernate JARs and you won't really find it. It's something that gets created when you extend HibernateDaoSupport in a special way. And the consuming class can't extend it directly either.
If you wish to use Hibernate templates to avoid having to inject a SessionFactory by hand, you must set up a helper class (abstract) thus:
package com.acme.user.entity; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** * With annotations in use, it's not possible to extend HibernateDaoSupport directly * in the DAO (Repository) class, hence this work-around, a custom class that does it * that's auto-wired to the session factory. */ public abstract class CustomHibernateDaoSupport extends HibernateDaoSupport { @Autowired public void anyMethodName( SessionFactory sessionFactory ) { setSessionFactory( sessionFactory ); } }
Then, the DAO class can be implemented thus:
package com.acme.user.entity; import java.util.List; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** * This is the repository or data-access object that isolates CRUD from the rest of the application * code, using Hibernate templating (and not Hibernate Criteria). */ @Repository public class AccountRepository extends CustomHibernateDaoSupport { @Transactional( readOnly = false, propagation = Propagation.MANDATORY ) public void create( Account account ) { getHibernateTemplate().save( account ); } @Transactional( readOnly = true, propagation = Propagation.MANDATORY ) public Account findByPhone( String phone ) { List< ? > list = ( List< ? > ) getHibernateTemplate().find( "from Account where phone=?", phone ); return ( Account ) list.get( 0 ); } @Transactional( readOnly = true, propagation = Propagation.MANDATORY ) public Account findByName( String name ) { List< ? > list = ( List< ? > ) getHibernateTemplate().find( "from Account where name=?", name ); return ( Account ) list.get( 0 ); } @Transactional( readOnly = false, propagation = Propagation.MANDATORY ) public void update( Account account ) { getHibernateTemplate().update( account ); } @Transactional( readOnly = false, propagation = Propagation.MANDATORY ) public void delete( Account account ) { getHibernateTemplate().delete( account ); } }
If you don't do it this way, likely you'll find getHibernateTemplate() gone missing and you won't find it in an JAR. Also, to link this code, you'll need something like org.springframework.core-3.1.0.RC2.jar in order to satisfy NestedRuntimeException.
https://dzone.com/articles/creating-a-web-application-with-spring-boot