I have created two separate web applications as well as a Restful API Server.
They are maven projects checked out as dynamic web projects within eclipse
Some dependancies I am using inlude Spring 3 MVC, Spring Security, Hibernate and JPA.
Both of my web applications and the API make use of a large number of the same domain models, DAO’s and Services in each applications.
They all have their own indepdant copies of model, dao, service.
Structures:
***Consumer App:***
-Model<br/>
..User.java<br/>
..Card.java<br/>
..Purchase.java<br/>
-Dao<br/>
..UserDAO.java<br/>
..CardDAO.java<br/>
..PurchaseDAO.java<br/>
-Services<br/>
..UserService.java<br/>
..CardService.java<br/>
..PurchaseService.java<br/>
***Admin App:***
Same with few different models, dao's and services.
***API Server:***
Same with few different models, dao's and services.
User:
@Entity
public class User implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -5232533507244034448L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotEmpty
@Size(min=2, max=15)
private String firstname;
@NotEmpty
@Size(min=2, max=15)
private String surname;
@NotEmpty
@Email
private String email;
@NotEmpty
@Size(min=6, max=10)
private String password;
@OneToOne(mappedBy="user", cascade={CascadeType.ALL})
private UserRole userRole;
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
private Set<Card> cards;
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
private Set<UserOffer> offers;
@Temporal(TemporalType.TIMESTAMP)
private Date dob;
@NotEmpty
private String sex;
.......
}
UserDAO:
@Repository
public class UserDAO extends AbstractJpaDAO<User> implements IUserDAO
{
@PersistenceContext
EntityManager entityManager;
public UserDAO()
{
setClazz(User.class);
}
public User findOneByEmail(String email)
{
return (User) entityManager
.createQuery("SELECT u FROM User u WHERE u.email = :email")
.setParameter("email", email).getSingleResult();
}
}
UserService:
@Service
public class UserService implements IUserService
{
@Autowired
private IUserDAO userDAO;
public UserService()
{
}
@Transactional
public List<User> getAll()
{
return userDAO.findAll();
}
@Transactional
public User getById(Long id)
{
return userDAO.findOne(id);
}
...
}
So as you can see, I need to remove these duplications and have one copy of each model, dao and service where possible.
Is the best approach to remove my models, dao’s and services from the web applications and API and place them in seperate projects/modules that should be included as a jar?
Has anyone suggestions on how to approach and implement this?
A brief overview from someone experienced with creating shared modules between multiple spring applications would be great.
Duplicated code, especially on such a large scale, is always a bad idea. Mark my words. Even if it’s not terrible right now, it will be as soon as you’ll have to modify one of the shared classes. The problems you’ll immediately experience:
Basically you have to create a separate module (common name is good, API is better, something domain-related is best) and depend on it. This separate module has all the common code and is built as a standalone JAR without any dependencies to client, server, etc.
All the remaining projects should simply depend on the common artifact. maven makes it use to maintain such projects.
One final hint: common JAR can not only contain classes, but also resources like XML configuration files. If you can, extract common configuration files into this JAR as well and simply include it in each client app. Since all such files will be available on CLASSPATH, Spring doesn’t care where they come from.