Franksoo is my project manager. Summary Time The company decided to make a new J2EE secondary development platform to replace the original development platform. The company allows Franksoo and I form a platform development project group, Frankso is the project manager. Now this platform integrated development phase has ended, and enter the project application phase. Below is our integrated work summary, introduce the issues we have encountered in our work and our choice.
1, the selection of architecture
First of all, we agree to develop a complete platform with our existing capabilities, there is not enough time and resource to develop a complete platform. Several excellent projects are selected in the existing open source projects to complete the project on time and meet the purpose of the project.
But before the platform project begins, we have their own ideas for the technical architecture of the platform. Franksoo's original idea is Struts Spring Hibernate, and my idea is Tapestry Hibernate.
However, Franksoo is very open, demonstrates Tapestry's classic example Workbench, introduces TapeStry to component-based programming methods, and he agreed to use TapeStry as a framework for implementing the web display layer. I think Franksoo's previous Struts development experience is one of the factors he makes this decision. FrankSoo gave me a nice introduction of Spring Framework. Wow, what an amazing framework! IOC, Declarative Transaction Support, Hibernate Session Management, Hibernate DAO Support ... These features are just what we need for a middle tire container.
As for Hibernate, this most successful open source ORM project, we all voted a ticket ^ _ ^
Finally we determine the platform's technical architecture is Tapestry Spring Hibernate.
2, architecture integration
The initial platform architecture draws on an architecture mentioned in how to integrate Tapestry and Spring articles [1]:
The Web layer TapeStry is responsible for data input output, responding to user events, and entering the work of the check, by accessing the preloaded WebApplicationContext (provided by Spring, containing all service beans) to get the service bean for the service layer to delegate the business operation they.
The bean of the Service layer is responsible for the USE CASE logic, Domain-related logic entrustments to the bean in Domain Model. Service completes the persistence of Domain Model via DAO. Service is responsible for database transactions and Hibernate session management (declaration through Spring) Transaction Management and Integrated Hibernate Session Management). Another important job of the Service layer is permissions and access control.
Domain Model is responsible for representing the data of the problem and Domain logic. DAO uses Hibernate persistent data as well. When implementing DAO, we use Spring Hibernate Dao Support, which greatly simplifies the code, and many methods are complete with simple lines. Interestingly, the final completed Hibernatedao code is still more than half of the Mockdao I wrote.
Such an architecture advantage is obvious, the level is clear, the responsibilities of each layer are also clear, facilitating the hierarchical design and development, combined with MOCK and Spring IOC, and Unit Test is also very easy. And the code of the back office, Domain Model and Dao Do not rely on the web container or the API of the EJB container, the portability is very good, the same code can be used in the web app can also be used in a normal Java app, just replace the UI layer. Follow this integrated architecture, we implemented A simple instance implements list paging query and display, data adds and derested, and Hibernate Criteria Query provides a relatively universal query mechanism. Using MiddleGen and Velocity we can automatically generate Hibernate mapping files, entity classes, and DAOs from the already built database table structure, which greatly reduces workload. We also have a pressure test on this small example (the amount of data in the test is 10,000 records), and it is determined that the platform does not have performance issues.
Through this example, we will pass through the entire architecture, and summarize the development processes applicable to use this architecture and need to do.
3, troubled our questions
In the implementation example and the current project application process, we found a number of headaches, some solved, some have not yet.
Question 1: Do you want to use DTO?
In the above architecture, we did not clarify how the service and Web layers were processed. We will discuss it for a long time, don't use DTO, and finally is not available.
Two main reasons for using DTO: 1, reduce the method call between the Web layer and the service layer, pass the data required by the Web to the web through a method call. 2, isolating the Domain Model and the Web layer.
The first reason is not established under our architecture. Because our architecture is centralized, Web and Service are in the same JVM, and the method call between them is not a huge consumption of EJB remote access.
The second reason is to consider. If you allow the object in Domain Model to pass to the Web layer, modify the Domain Model will affect the web layer. If you use DTO, then Domain Model implements changes will not affect the web. However, a large number of changes are not Domain Model implementation changes, but a change in the Domain Model interface, such as a Domain Model adds an attribute, and this property requires user modification, then this time must be modified, no matter whether it is Use DTO. And using DTO, you need to maintain a large bunch of objects, or their builder, which is very boring, and it is easy to go wrong.
Based on these considerations, we didn't use DTO, but to choose Domain Model directly to the web layer. Here is the modified architecture map (huh, modified the figure [2]).
Question 2: Entity Like Domain Model Or Rich Domain Model?
We use MiddleGen to automatically generate Hibernate mapping files, Entity classes, and DAO classes, but generated Entity only contains simple properties and getter, setter methods. So we have encountered a question: Does our Domain Model do not include Domain Logic? If included, how to combine with the automatic generation tool?
After we discuss, we think that a Rich Domain Model is still necessary, which can reduce the repetition code in the service to improve the reuse.
How to combine automatically? Use the tag to generate an abstract base class, we inherit these automatic generated base classes, add business methods.
Question 3: Model Driven or Data Driven? The way Model Driven is also Data Driven. Everyone has a warm discussion. We are mainly affected by Rod Johnson [3], which uses Data Driven's way. Before you do a database design, generate a library table, then generate the Hibernate mapping file and Entity and DAO with MiddleGen. But we have two problems in this approach after entering the project application:
a) Database design only describes the static data to be managed by the system, we still have object-oriented analysis to reflect the dynamic behavior of the system. Especially when the system's business is not just a simple CRUD operation, this problem is more serious.
b) Database design In order to optimize performance, several data should be put into an entity in a single entity. This is unacceptable if this extreme coarse particle size entity is mapped directly into an Entity class. Object-oriented analysis design models are quite fine. This situation also has to be object-oriented analysis, which is clear that the big table of the coarse particle size should be mapped into the fine-grained object.
Perhaps we should try Model Driven, generate Domain Model, Hibernate Dao, Hibernate Mapping, database table, simple service, and TapeStry pages in the front desk with AndroMDA.
Question 4: How does the Hibernate session life cycle management?
For the lifecycle of Hibernate Session, we use the session-per-transaction mode, which is not used in Open Session in View mode. Although Hibernate Team thinks that this method is not bad, and Freeroller and Atlassian's Conflunce use Open session in view model, but we have no well-grasp of the impact of it, so it is temporarily discarded. If the Web layer is to access the data of Lazy Load, you need to call the service's business method to get the data.
Question 5: How is USE Case Logic and Domain Logic?
Service is responsible for USE Case Logic, Domain Model is responsible for Domain Logic. Such division looks very good, it is very troublesome. How to determine what is use case logic, what is DOMAIN logic? TBD.
Question 6: How does the service level determine?
This problem is really annoying, just considering the way Usecase Controller, each Usecase corresponds to a service, but it is found that it must be too low, and many places must be multiplexed.
Another way is to use Package Level Service, each package is a service, which is reused, but it feels too dead, not good.
There is no good way now, I have to determine how many services needed according to the specific situation during detailed design. TBD.
Question 7: How to set the permissions? How to check?
Permissions settings are also a headache problem. We want to set permissions according to USE CASE, each use case. Direct processing directly in the role settings is a very clear permission. However, issues have been found during the authority verification: If the permissions are verified in the service method, and this method is used in multiple usage (multiplex service), then this service method needs to check multiple permissions; if each The service method corresponds to a permission, then the permissions are too thin, not like a complete business as the USE case authority. It is really trouble! Tbd.quake Wang:
Question 1: Do you want to use DTO?
NO DTO, directly passing Domain Object to Tapestry's web layer, using TapeStry to provide powerful data binding and component feature convenient
Question 2: Entity Like Domain Model Or Rich Domain Model?
Domain Model does not include complex Domain Logic, just as a Data Model Bean, plus some simple logic, such as AddChild, setting Child's PARENT such simple logic.
Question 3: Model Driven Or Data Driven?
This is not a big problem for me. Personal habit, I think it is model Driven or Data Driven, and the final design should be very similar to the same needs. I think about it from 2, while doing MODEL, I have to consider the structure of the database, and make corresponding adjustments, there is no problem. No code is generated, just use Hibernate's Eclipse Plugin (Hibernate Synchronizer) to help me do some code assist.
Question 4: How does the Hibernate session life cycle management?
There is currently no Open session in view, just like you, ready to all need objects in Service.
Question 5: How is USE Case Logic and Domain Logic?
This problem does not exist because Domain Model is not Domain Logic.
Question 6: How does the service level determine?
Since there is no Domain Logic in Domain Model, the service's function is very fine, try to use, a package may have multiple services, feeling good, not too dead.
Question 7: How to set the permissions? How to check?
This is also a problem I don't want, because different needs, permission settings are different, it is difficult to use AOP to be a universal aspect.
1. DAO practice:
I am not a DAO for each Domain Object, but the entire system is a DAO (PersistenceManager), only 3 methods of Create, Update, Delete Entity. Also write a DAO, specifically do query (QueryManager), use Hibernate's Named Query to do commonly used queries, use criteria to do dynamic queries based on user input. I don't know how your approach is? In addition, Criteria and Named Query are actually Hardcode, Object Attribute Name, have to remember to modify these code manually, Unit Test is difficult to overwrite the code in all criteria search and named query, this is not very convenient The place. 2. Spring and TapeStry integration
At present, only Spring to Service Layer, Tapestry is called through the object of Global (playing the role of Service Locator), and there is still a lot of Dirty Code at Domain Tapestry, in fact, can also be solved with AOP. If you can be like WebWork2, all Actions can get from Spring, get Page via Spring
Listeners, it will be much convenient, but TapeStry also has its own type of enhancement, it seems to have some conflict, there is no good idea.
By the way, 3 tools I use in the project (all eclipse plugins):
1.
Http://spindle.SourceForge.net development Tapestry must
2.
Http://springui.sourceforge.net Write Spring Application Context File Accessibility Tools
3.
Http://www.binamics.com/HibernateSynch/ Hibernate Developed Auxiliary Tools.