I know there are many questions about my problem and I've read a lot, but I'm still feeling little bit stupid, because I still haven't got it. So I'm trying it on my particular problem.
I'm implementing the school work. It should be a part of the information system, which has to be layered. We have to write it in Java or C# (I've chosen Java). We have to use two different data sources and two different views, in my case, oracle db and xml as data source and Java Swing and JSF as views.
According to the book "Patterns of Enterprise Application Architecture by Martin Fowler" there are three principal layers:
Data source layer: I've generated entities using Hibernate ORM, I've created data access objects to implement simplier "interfaces" to getting the data.
Domain layer: ...
Presentation layer: I've created the Swing GUI and some .xhtml pages with MVC logic
If there wouldn't be any "calculations" in the system, but only simple achieving and returning data, I'm done, everything is ok. But I'm, for example, implementing the system, which should manage the competitions of the sport dancing, and during the competition I need to generate sets of couples for every round, after the competition I need to calculate points of every dancer, increment points if necessary and so on.
I know, that it is the responsibility of the Domain layer (business logic), but where in my code with? What names for these objects should I choose and where to put them in my code structure?
My structure:
hibernate.cfg.xml (configuration of hibernate)
hibernate.reveng.xml (reverse engineering file of hibernate)
isets.dao (package)
isets.dao.hibernate (package)
HbmCompetitionDao.java (data access object of Competition entity)
...
isets.dao.xml (package)
... (data access objects of another entities, which are stored as XML)
isets.entities (package)
Competition.hbm.xml (generated entities)
Competition.java
...
isets.util (package)
HibernateUtil.java (file to get session factory object)
Where should I put my business logic and what should be the names of these classes?
Thank you very much for your help. Bye :-)
Usually domain layer means "entities" (models for domain) and domain services.
Entities hold all business logic related to them. Validations (checking that they're in correct state) and calculations are usually put in the property setters/getters, while operations for transforming data are exposed via public methods.
Domain services are classes that operate with multiple entities and do some calculations and/or transformations between entities.
A few things to consider. In order for this design to work properly (so it is testable, decoupled etc), dependency injection (DI) must be used. Domain should never be bothered by getting or saving data etc. It should be clearly decoupled and all its dependencies should be known upfront.
If it is a simple application it may be wise to combine domain layer and data access layer, so objects that are created from ORM are already entities. Just add domain services (if you need them). Use then the same entities on presentation as well (as model for MVC). This will decrease the need for mappers to map between ORM made objects (lets call them dbos), entities and possible models needed for presentation. Of-course if you need different objects for each layer, by all means create them. Just don't over complicate if it is not needed.
One of the possibilities is to structure you application as follows:
1) #Entity annotated POJO represent your data layer representing tables, relationships between them, etc using JPA
2) Stateless session beans implementing Session Facade desing pattern wrap your container managed CRUD operations. There are typically one facade per entity, they usually look like this:
#Stateless
public class FooFacade extends AbstractFacade<Foo>{
#PersistenceContext
EntityManager em;
public EntityManager getEM() {
return em;
}
public void save (Foo entity) {
getEM.persiste(Foo.class, entity);
}
public void reload (Foo entity) {
getEM.refresh(entity);
}
//other similar stuff
}
AbstractFacade is an abstract class that provides genetic find and other operations that look identical in all facade classes (to avoid duplicate code). This e-commerce sample application can be used as a great example of this strategy. The classes are usually named as EntityName + Facade.
3) Stateless session beans that realise your business logic (calculations for competitions in your case or adding goods into basket, implementing checkout, etc. for ecommerce app). Usually they talk to data layer via *Facade EJBs mentioned in part 2 above. This part of the aforementioned tutorial realises these EJBs.
4) Servlets to which your UI layer will refer their request. Servlets will utilize EJBs from part 3 to serve the requests.
5) UI layer - JavaFX, Swing, JSF, JSP, Apache Wicket framework - add anything you like.
Such a structure gives you both flexibility and scalability. Centring your business logic in stateless beans means you can scale well because they are pooled and every instance in the pool can equally be used when you application (e.g. servlet) needs talk to an instance of such a bean.
I strongly recommend you to thoroghly read through the ecommerce tutorial on Netbean's website to see the concrete implementation of this scheme. Here is the download link for the source code of the application, AffableBean ecommerce system, built through the tutorial.
Related
I'm (trying to :) using spring-boot-starter-data-rest in my spring boot app to quickly serve the model through true, fullblown, restFULL api. That works great.
Question 1 (Security):
The advantage of Spring JpaRepository is I don't need to code basic functions (save, findAll, etc). Is it possible to secure these auto-implemented methods without overriding all of them (wasting what Spring provided for me)? i.e.:
public interface BookRepository extends JpaRepository<Book, Long> {
#PreAuthorize("hasRole('ROLE_ADMIN')")
<S extends Book> Book save(Book book);
}
.
Question 2 (Security):
How to secure a JpaRepository to prevent updating items the loggeg-in user is not an owner?
i.e.: User is allowed to modify only his/her own properties.
i.e.2: User is allowed to modify/delete only the Posts he/she created.
Sample code is highly welcome here.
.
Question 3 (DTOs):
Some time ago I had an argue with a developer friend: He ensisted that there MUST be DTOs returned from Spring MVC controllers. Even if the DTO is 1-1 copy of the model object. Then I reserched, asked other guys and confirmed it: DTOs are required to divide/segregate the application layers.
How this relates to JpaRepositories? How to use DTOs with Spring auto serverd rest repos? Should I DTOs at all?
Thanks for your hints/answers in advance !
Question 1: Security
Some old docs mention:
[...] you expose a pre-defined set of operations to clients that are not under you control, it’s pretty much all or nothing until now. There’s seemingly no way to only expose read operations while hiding state changing operations entirely.
which implies that all methods are automatically inherited (also, as per standard java inheritance behavior).
As per the #PreAuhtorize docs, you can place the annotation also on a class / interface declaration.
So you could just have one basic interface extend JpaRepository
#NoRepositoryBean // tell Spring not create instances of this one
#PreAuthorize("hasRole('ROLE_ADMIN')") // all methods will inherit this behavior
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {}
and then have all of your Repository's extend BaseRepository.
Question 2: Security
I'm going to be a little more general on this one.
In order to correctly regulate access to entities within your application and define what-can-see-what, you should always separate your project into different layers.
A good starting point would be:
layer-web (or presentation-layer): access to layer-business, no access to the db-layer. Can see DTO models but not DB models
layer-business (or business-layer): access to the db-layer but no access to the DAO
layer-db (or data-layer): convert DTO -> DB model. Persist objects and provide query results
In your case, I believe that the right thing to do, would be therefore to check the role in the layer-business, before the request even reaches the Repository class.
#Service
public interface BookService {
#PreAuthorize("hasRole('ROLE_ADMIN')")
ActionResult saveToDatabase(final BookDTO book);
}
or, as seen before
#Service
#PreAuthorize("hasRole('ROLE_ADMIN')")
public interface BookService {
ActionResult saveToDatabase(final BookDTO book);
}
Also, ensuring a user can modify only its own objects can be done in many ways.
Spring provides all necessary resources to do that, as this answer points out.
Or, if you are familiar with AOP you can implement your own logic.
E.g (dummyCode):
#Service
public interface BookService {
// custom annotation here
#RequireUserOwnership(allowAdmin = false)
ActionResult saveToDatabase(final BookDTO book);
}
And the check:
public class EnsureUserOwnershipInterceptor implements MethodInterceptor {
#Autowired
private AuthenticationService authenticationService;
#Override
public Object invoke(Invocation invocation) throws Throwable {
// 1. get the BookDTO argument from the invocation
// 2. get the current user from the auth service
// 3. ensure the owner ID and the current user ID match
// ...
}
}
Useful resources about AOP can be found here and here.
Question 3: DTO's and DB models
Should I DTOs at all?
Yes, yes you should. Even if your projects has only a few models and your are just programming for fun (deploying only on localhost, learning, ...).
The sooner you get into the habit of separating your models, the better it is.
Also, conceptually, one is an object coming from an unknown source, the other represents a table in your database.
How this relates to JpaRepositories?
How to use DTOs with Spring auto serverd rest repos?
Now that's the point! You can't put DTO's into #Repositorys. You are forced to convert one to another. At the same point you are also forced to verify that the conversion is valid.
You are basically ensuring that DTOs (dirty data) will not touch the database in any way, and you are placing a wall made of logical constraints between the database and the rest of the application.
Also I am aware of Spring integrating well with model-conversion frameworks.
So, what are the advantages of a multi-layer / modular web-application?
Applications can grow very quickly. Especially when you have many developers working on it. Some developers tend to look for the quickest solution and implement dirty tricks or change access modifiers to finish the job asap. You should force people to gain access to certain resources only through some explicitly defined channels.
The more rules you set from the beginning, the longer the correct programming pattern will be followed. I have seen banking application become a complete mess after less then a year. When a hotfix was required, changing some code would create two-three other bugs.
You may reach a point where the application is consuming too many OS resources. If you, let's say, have a module module-batch containing background-jobs for your application, it will be way easier to extract it and implement it into another application. If your module contains logic that queries the database, access any type of data, provides API for the front-end, ecc... you will be basically forced to export all your code into your new application. Refactoring will be a pain in the neck at that point.
Imagine you want to hire some database experts to analyze the queries your application does. With a well-defined and separated logic you can give them access only to the necessary modules instead of the whole application. The same applies to front-end freelancers ecc... I have lived this situation as well. The company wanted database experts to fix the queries done by the application but did not want them to have access to the whole code. At the end, they renounced to the database optimization because that would have exposed too much sensitive information externally.
And what are the advantages of DTO / DB model separation?
DTO's will not touch the database. This gives you more security against attacks coming from the outside
You can decide what goes on the other side. Your DTO's do not need to implement all the fields as the db model. Actually you can even have a DAO map to many DTO's or the other way around. There is lots of information that shouldn't reach the front-end, and with the DTO's you can easily do that.
DTO are in general liter than #Entity models. Whereas entities are mapped (e.g #OneToMany) to other entities, DTO's may just contain the id field of the mapped objects.
You do not want to have database objects hanging around for too long; and neither being passed around by methods of your application. Many framework commit database transactions at the end of each method, which means any involuntary change done onto the database entity may be committed into the db.
Personally, I believe that any respectful web-application should strongly separate layers, each with its responsibility and limited visibility to other layers.
Differentiation between database models and data transfer objects is also a good pattern to follow.
At the end this is only my opinion though; many argue that the DTO pattern is outdated and causes unnecessary code repetition any many argue that to much separation leans to difficulty in maintaining the code. So, you should always consult different sources and then apply what works best for you.
Also interesting:
SE: What is the point of using DTO (Data Transfer Objects)?
Lessons Learned: Don't Expose EF Entities to the Client Directly
Guice Tutorial – method interception (old but gold)
SO: Large Enterprise Java Application - Modularization
Microsoft Docs: Layered Application Guidelines
The 5-layer architecture
#Entity
class MyEntity {
//some properties to be explosed to REST, some not
}
I have some database classes that I want to explose via REST using spring.
Is it advisable to create a DTO for each database class, copying over all properties needed to be exposed.
Because certainly some fields like the id should never be available via rest. But these fields can maybe be annotated accordingly so they are ignored during REST offer?
Is writing DTOs still advisable today if they just serve as plain data containers that get the fields copied over from DB?
Some points I can think while deciding:
Arguments against common model for persistence & web service
In many applications the rest services are written to provide you a fully constructed object & not really a normalized view of the data. For example your rest service may return an Employee object with a Department object, wheras your db model just has a deparment id
Modifications in 1 model do not affect the other. For example you decide to change a String in the persistence model to an integer, you may still be ok with keeping it as a string in your rest service
You may have attributes in the rest model which make no sense to be on the persistence model or vice versa
If you are distributing your model jar (like a client API) then it may end up with a dependency on your persistence framework which your clients may not want/support.
Arguments supporting common model for persistence & web service
Avoid copying/cloning data for every interaction
Avoid duplicate maintenance or possible issues when an attribute is added in 1 model and forgotten in another
In my experience if you are creating services exclusively to be consumed by your own application (like a UI) and have tight control on those services, you might get away with using a common model
However if the rest API is intended for broader use and for longevity I would go with separate models. You can use spring's beanutils to ease the conversion of models from one format to other. See example here
Is it discouraged to have "extra" functionality inside a hibernate javabean? For example, a "save", "publish", or even static "get by id" method? And other potential variables such as locks, bells and whistles?
If so, where are we supposed to put these extra features that are supposed to be in each object we are dealing with? If for example we created a wrapper class ArticleWrapper that includes the POJO Article as its own private member variable, which doesn't have a mapping to Hibernate, then it wouldn't work because Hibernate can only get a list of Articles, not a list of ArticleWrappers.
I guess the reasons for this are because they follow a specific well tested pattern for this, but that is not the only pattern to deal with database manipulation.
The one you describe sounds more like the Active Record Pattern Pattern.
Some frameworks implement Active Record and then their object models mix data and functionality together, pretty much like you describe. I have seen this pattern in Ruby on Rails Active Records and in Python's framework named Django.
In this pattern every domain object represents a row in the database and carries both data and behavior.
Martin Fowler in his book on Enterprise Application Architecture Patterns (and corresponding catalog page) mentions a few other well known ways to deal with your data source layer:
Table Data Gateways
Row Data Gateway
Data Mapper
Active Record
The book and the catalog delves into many other patterns for object-relational mapping.
Layered Design
In the classical way you describe with Hibernate, the entities are just placeholders for data, but contain no logic whatsoever. Under this pattern you would most likely have a data access layer or repository layer around your entities that deals with recovering entities from the underlying data source and updating them back.
This layer is the one that deals with CRUD operations.
interface ArticleRepository {
Article findById(Integer articleId);
List<Article> findByAuthor(Integer authorId);
Article save(Article article);
void delete(Integer articleId);
}
On top of this layer, you have a service layer which is the one that exposes the business logic to the users of your application.
interface ArticleService {
void publishArticle(String author, Date date, String title, String contents);
List<Article> getFeaturedArticles(Date date);
void unpublishArticle(Integer articleId);
}
On top of this layer, most likely you define some form of integration layer to expose this service layer to the application users in many different ways, like through RESTful or SOAP Web services, or RMI, EJBs or whatever other technology you know out there.
By not putting any kind of logic in your entities, they serve well their purpose of data carriers and can be reused in different service layers if necessary.
You may want to take a look at the framework like Spring Data that fosters this type of design. It makes it all more clear where every piece should go.
I guess writing code is not only about making it compiling and running. To make code clean and easy to maintain developers have come up with various design patterns such as DataAccessObject (or dao) for this particular situation. Following OO good practices will make developers' work more efficient, especially if they work on big projects, with time code that doesn't present decent level of cohesion and looks like a bucket of dirty laundry will become impossible to maintain. Remember - just because you can do something doesn't mean you should.
I need some advice on designing an "Integration Tier" of an N-Tiered system in Java. This tier is responsible for persisting and retrieving data for the "Business Tier" (located on a separate server). I'm new to J2EE and I've read a few books and blogs. The alphabet soup of technology acronyms is confusing me so I have a handful of questions.
First, what I have so far: I'm using JPA (via Hibernate) for persisting and retrieving data to a database. I made my data access objects EJBs and plan on deploying to an application server (JBoss) which makes transactions easier (they're at the function level of my DAOs) and I don't have to worry about getting a handle to an EntityManager (dependency injection). Here's an example of what things look like:
#Entity
class A{
#Id
Long id;
#OneToMany
List<B> setOfBs = new ArrayList<B>;
}
#Entity
class B{
#Id
Long id;
}
#Remote
public interface ADAO{
public A getAById(Long id);
}
#Stateless
class ADAOImpl implements ADAO{
#PersistenceContext
EntityManager em;
public A getAById(Long id){ ... }
}
My question: How should the Business Tier exchange data with the Integration Tier. I've read up on RESTful services, and they seem simple enough. My concern is performance when the frequency of gets and sets increases (HTTP communication doesn't seem particularly fast). Another option is RMI. My DAOs are already EJBs. Could I just have the Business Tier access them directly (via JNDI)? If so, what happens if the #OneToMany link in the example above are lazily loaded?
For example if the Business Tier does something like the following:
Context context = new InitialContext(propertiesForIntegrationTierLookup);
ADAOImpl aDao = (ADAOImpl) context.lookup("something");
A myA = aDao.getAById(0);
int numberOfBs = myA.setOfBs.size();
If the setOfBs list is loaded lazily, when the Business Tier (on a separate server) accesses the list, is the size correct? Does the list somehow get loaded correctly through the magic of EJBs? If not (which I expect), what's the solution?
Sorry for the long post. Like I said I'm new to J2EE and I've read enough to get the general idea, but I need help on fitting the pieces together.
When you call size() on lazy collection, it gets initialized, so you'll always get correct size no matter which interface you're using - Remote or Local.
Another situation is when you're trying to use JPA classes as data transfer objects (DTO) and request them via Remote interface. I don't remember any lazy initialization issues here, cause prior to transmission all objects have to be serialized (with lazy collections initialized) on server side. As a result, the whole object graph is passed over network, which might cause serious cpu and network overheads. In addition, for deserialization to be possible, you will have to share JPA classes with remote app. And that's where and how 'EJB magic' ends :)
So, once remote calls are possible, I'd suggest to start thinking of data transfer strategy and non-JPA data transfer objects as additional data layer. In my case, I've annotated DTO classes for XML binding (JAXB) and reused them in web-services.
Short answer: If you are using an "Integration Layer" approach, the things you should be integrating should be loosely coupled services, following SOA principles.
This means you should not be allowing remote calls to methods on entities that could be making calls to the framework under the lid on another server. If you do this, you are really building a tightly coupled distributed application and you will have to worry about the lazy loading problems and the scope of the persistence context. If you want that, you might like to consider extended persistence contexts http://docs.jboss.org/ejb3/docs/tutorial/extended_pc/extended.html.
You have talked about a "business tier", but JPA does not provide a business tier. It provides entities and allows CRUD operations, but these are typically not business operations. a "RegisterUser" operation is not simply a question of persisting a "User" entity. Your DAO layer may offer a higher level of operation, but DAOs are typically used to put a thin layer over the database, but it is still very data centric.
A better approach is to define business service type operations and make those the services that you expose. You might want another layer on top of your DAO or you might want to have one layer (convert your DAO layer).
You business layer should call flush and handle any JPA exceptions and hide all of that from the caller.
The issue of how to transfer your data remains. In many cases the parameters of your business service requests will be similar to your JPA entities, but I think you will notice that often there are sufficient differences that you want to define new DTOs. For example, a "RegisterUser" business operation might update both the "User" and "EmailAddresses" table. The User table might include a "createdDate" property which is not part of the "RegisterUser" operation, but is set to the current date.
For creating DTOs, you might like to look at Project Lombok.
To copy the DTO to the Entity, you can use Apache Commons BeanUtils (e.g., PropertyUtils.copyProperties) to do a lot of the leg work, which works if the property names are the same.
Personally, I don't see the point in XML in this case, unless you want to totally decouple your implementations.
Suppose i have class USER with attributes.
In some examples i see UserService class defined for some functions.
I am confused which things or functions should written in User Class and which things in UserService.
For e,g If i want to write some function To Validate users in database like
validate(user,pass)
Where should write those function
Also if i have class ShoppingProducts
and i want to get all prodcuts shopped by particular user in which class should i write that function i mean in product class or UserService or ProductService
This is a typical example of domain model vs anemic model.
There's a lot of theory in this discussion, but a practical advice from me is to:
put all methods that can operate on the User properties only in the User class.
put all methods that require database access, accessing web services, or other layers, in the service.
See this related article of mine.
I won't go into the battle of domain vs anemic or SOA data separate from behavior.
I will say that I think of service's as behavior that spreads across multiple domains (multiple domain objects) and deals with data transfer objects (ie don't put the DTOs in your domain objects).
With REST being so popular these days and the fact the Resources (REST since) are not Models you always seem to need DTOs and Service classes.
On other hand with AspectJ, Annotations and some other magic you can really push the edge of Domain Driven design but I still think you should not reference other domain objects in a domain object.