This is Janis Kazakovs's Typepad Profile.
Join Typepad and start following Janis Kazakovs's activity
Join Now!
Already a member? Sign In
Janis Kazakovs
Recent Activity
Janis Kazakovs is now following Account Deleted
Jun 26, 2012
Thanks for info. It actually makes sense, since HomeDir and ConfigFile allow you to specify location of the JCR repository local to you Glassfish instance. While this is not always the case, like in your situation.
Frankly, I do not know much about it. Neither can I find anything on the net. The only think I know is that you should use either repositoryURI or homeDir during connector configuration. Probably, the intention of repositoryURI is the same as of homeDir, but syntax is different, something like this jcr-jackrabbit://jackrabbit. Sorry, but I can't provide you much info on that.
Well, yes. You are right. It is rather obvious, but I could be more explicit. Thank you for you comment. I will add this to the post.
You may access a working example from this blog:
Toggle Commented Nov 2, 2011 on Java:AOP:Logging at Janis Kazakovs's blog
You are right, lib/ext will make jcr-2.0.jar an installed extension. I have overlooked that. Thanks for feedback. Looks like this post is getting a perfect shape ;)
Hi Sebastian, Thanks for hint! Even though I have mentioned that at the end of the post, you are right that it should be done before all the other steps. Janis
Hello Victor, It is difficult to say what would a right solution to this problem. I still think it is a matter of a proper design. However, in order to make a correct design proposal a more details of a business case are needed. You have mentioned save() method on your session bean, if you just do not defined this method on a session bean then a client won't have a possibility to directly save the state of a Contract, while only ContractBean will decide when it should happen. In this case, ContractBean.endContract() should do a job well and a client won't have a possibility to change a state of a Contract otherwise, even if it calls Contract.end() directly. So, your invariants should be preserved, if only I am not missing something. Another think I would like to add with regards to the save(). A client, normally, should not know anything about a database specific operations, it should be purely a responsibility of your session bean. This is why there is an additional abstraction layer represented by a session bean, which encapsulates data access logic and carries other responsibilities specific to a business case or other, such as auditing that you have mentioned. There is an exception to this rule and this is what I have mentioned in the blog above when I've talked about the Gateway. In classical scenario, as well as in your case you have a stateless session bean (i.e. ContractBean), which is your Session Facade. Session Facade is normally a boundary for transaction management, which means that on execution of a method on a Session Facade a transaction will begin and will, correspondingly, end when a method returns. Thus, a Session Facade encapsulates your business logic and exposes the result of that logic execution to a calling client by returns a DTO, which could be a detached Entity. However, according to a Leaking Abstraction principle every abstraction is leaking. So, one crazy idea that may come to your mind is why not to make it leak even more and break encapsulation completely. This is what the Gateway is about. You can archive the above by letting a Gateway return not the detached Entities, as it happens in case of Session Facade, but rather Entities that are still attached to a persistence context. In this case you, a client is able to manage a state of your Entity and call to Contract.end() would indeed change the state of your Contract. A Gateway, in turn, will defined CRUD like method on its interface, such as save() or update(). A Gateway should be used in caution and only in some specific cases. It my lead to some problems, such as scalability or memory leakage, however the performance should be a gain. Janis
Hello Victor, I do not think there is something wrong with the way you define your business logic. It is just one way of doing it. So, I do not really have anything to put against your approach. As long as I know there are two way to implement a business logic and they are both described by means of two design patterns mentioned in Martin Fowler's book, namely Transaction Script and Domain Model. Which approach to follow is more a matter of an architectural decision that should be made somewhere on early stage of a project, since it will influence a further evolution of your application. I have partially mentioned it in the above blog, but in case of the Transaction Script, from one side, you will have a thin domain model, which will serve as a wrapper of you data in the database, and from another side, a thick service layer that will encapsulate all your business functionality. This approach is considered easy to start with on early stage of a project, but it may create problems later on, when you requirements change and functionality grows, since it may get more difficult to maintain your business logic and add new functionality to reflect new requirements. Thus, in case of the Transaction Script you will have something like ContractManager that, as you have mentioned it, will interact with Entity in order to change its state by calling setters on it and then merge that Entity to a persistence context. In case of the Domain Model the situation is opposite, you will end up having a thin service layer and thick domain model, since all you business logic will be implemented in the domain model and service layer will be used only as a layer to access your business functionality. This is when you may start following Domain Driven Design best practices, by implementing Aggregates, Repositories and etc. Personally, I prefer this approach more then the first one, since it better reflects business use cases defined by the requirements. In DDD there is a term for this, ubiquitous language, I think. It is also considered that domain model is more flexible and is easier to extend, when requirements change or new ones arrive. You will need, however, put more effort and time to design a domain model in order to better reflects your business cases. This may be different from the Transaction Script, where you can deliver some functionality early, since you can directly start implementing your functional requirements and show it to a customer, which may be also more preferred in the Agile environments. However, an application that implements only functional requirements without consideration of non-functional requirements will turn out to be a nightmare on a later stage. This is another argument for using Domain Model, since it makes me think more about making my application extensible, reusable and so on. This is rather a long response. I do not know if it helped you in any way, but I would simply distinguish two ways of designing your business layer. Which one to choose is more a matter of a design decision. P.S.: With regards to the security issues related to DTO's I do not have much to say. I wonder myself, which these could be. However, the security requirements are normally solved by other means and if your application has confidentiality requirements, then they could be solved by securing communication channel by applying some encryption algorithms. You should be able to configure tunnel between your web and application server, but this is more administrative task. There is also a design pattern called Obfuscated Transfer Object, which could be applied in case of DTO's. Janis