Spring and manually created DAOs how to refactor to enable hasPermisions on such DAOs objects - spring

I have got Dao implentation like this
public class EntityDao<T> {
private Class clazz;
private SessionFactory sessFactory;
public EntityDao(Class clazz, SessionFactory sessFactory) {
this.clazz = clazz;
this.sessFactory = sessFactory;
}
.... dao methods
}
and factory for retriving and storing particular dao
EntityBeanDaoFactory {
private HashMap<EntityDaoType, EntityDao> daoMap = new HashMap<EntityDaoType, EntityDao>();
// return dao from daoMap if exists a if not create it and put it in the map then return dao
public EntityDao createDao(EntityDaoType entityType) {
switch (entityType) {
case mySpecialDaoTYPE:
if (!daoMap.containsKey(entityType)) {
EntityDao<Type> mySpecialDao = new EntityDao(Type.class, sessFactory);
daoMap.put(entityType, mySpecialDao);
}
return daoMap.get(entityType);
}
}
now I want to annotate dao methods with #PreAuthorize("hasPermission()") but spring doesn't know about daos created this way and I am not able to refactor whole project at once so I have created dao ,on wich I need to use the annotation, inside aplicationContectxt.xml
<bean id="mySpecialDao" class="..EntityDao" >
<constructor-arg>
<value>myClass</value>
</constructor-arg>
<constructor-arg ref="sessionFactory" />
</bean>
inside the factory I have changet behavior for creating this particular dao like this
if (!daoMap.containsKey(entityType)) {
EntityDao<Class> dao = (EntityDao<Class>) AppContext.getApplicationContext().getBean("mySpecialDao");
daoMap.put(entityType, dao);
}
is there some better way how to make spring aware of my DAOs ? I mean is there way how to make Spring aware of manualy created instancess ?

You could do this using Spring AOP support using AspectJ. Read more here: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-atconfigurable
After enabling this, Spring would be aware of any instances created of classes annotated with the Configurable annotation. Spring would then be able to recognize the PreAuthorize annotations.

Why do you need a factory to create DAOs? That's what the Spring application context is.
You look like you want to restrict the ability to call DAO methods using role based security. I think that's fine, and possible to do, but you need not restrict creation of the DAO. Create it using Spring and then restrict access. Your way is overkill and unnecessary.

Related

Wiring multiple beans with the same dependency via Spring Boot #Configuration

In older Spring MVC apps, where you'd specify application.xml and declare your app's beans so that Spring DI could instantiate them and wire them together, you might have something like this:
<bean id="chargeFactory" class="com.example.myapp.ChargeFactory" />
<bean id="paymentService" class="com.example.myapp.DefaultPaymentService">
<ref id="chargeFactory"/>
</bean>
<bean id="chargeAuditor" class="com.example.myapp.ChargeAuditor">
<ref id="chargeFactory"/>
</bean>
Which might help wire up the following code:
public interface PaymentService {
public void makePayment(Payment payment);
}
public class DefaultPaymentService implements PaymentService {
#Autowired
private ChargeFactory chargeFactory;
#Override
public void makePayment(Payment payment, String key) {
Charge charge = chargeFactory.createCharge(key);
charge.doCharge(payment);
}
}
public class ChargeAuditor {
#Autowired
private ChargeFactory chargeFactory;
public void auditAllCharges(String key) {
List<Charge> charges = chargeFactory.getAllCharges(key);
// blah whatever
}
}
How do you accomplish the same bean wiring in Spring Boot with the #Configuration class? For example:
#Configuration
public class MyAppInjector {
#Bean
public ChargeFactory chargeFactory() {
return new ChargeFactory();
}
#Bean
public PaymentService paymentService() {
return new DefaultPaymentService(chargeFactory());
}
#Bean
public ChargeAuditor chargeAuditor() {
return new ChargeAuditor(chargeFactory());
}
}
This might work but introduces some issues:
It would force me to have to write value constructors for all my classes, which goes against everything I see in literally every tutorial/article I've come across. Plus, if I had to do that, then there's no real value to #Autowired anyways...
At this point I'm essentially doing "DIY DI", which is OK, except I'm trying to deliberately use Spring DI :-)
Every time I call chargeFactory() I'm getting a new (prototype-style) ChargeFactory instance. Maybe I want a singleton. Using this approach I have to hand-roll my own singleton implementation.
Sure, I can do all of this, but I feel like I'm flagrantly misusing/misunderstanding how #Configuration is supposed to be used, because it seems like I'm introducing a whole lot of DIY/homegrown code to solve something Spring DI should be able to do for me.
How would I reference the chargeFactory bean and wire it into both the "provider methods" for the paymentService and chargeAuditor beans? Again, looking for the Java-based #Configuration solution instead of writing an XML document to define the wirings.
I found this article which seems to be the only tutorial/documentation (surprisingly) on wiring Spring Boot apps via #Configuration (which leads me to believe there might be other/better methods...), but it does not address:
How to specify singleton vs prototype bean instantiation patterns
If multiple instances of a bean-class exist, how do I specify which instance gets wired into which dependency?
How do I get around not defining value constructors for all my classes, and just let Spring/#Autowired inject fields automagically?
When you call chargeFactory() , spring won't create new instance everytime. Give it a try and see. Same object will be returned. Anyways
You can do something like this.
#Bean
public PaymentService paymentService(ChargeFactory chargeFactory) { return new DefaultPaymentService(chargeFactory); }

How to avoid lazy fetch in JSON serialization using Spring Data JPA + Spring Web MVC?

I have a solution using Spring Data JPA and a REST Controller in Spring Web MVC. The persistence provider is Hibernate.
The persistence layer is built using Spring Repositories and between de REST Controller and the repository exists a Service Layer:
Entity <--> Repository <--> Service <--> Controller
At entity level, I have #OneToMany fields with FetchType = LAZY.
When the REST Controller make the serialization, the fetching is made, but this is undesirable in some cases.
I already tried with #JSONInclude Jackson annotation and the serialization still occurs.
Can somebody help me with a proved solution?
If I understood you properly, you want to serialize only when the lazy loaded collection is fetched, but you don't want the serialization to trigger the fetching.
If that is the case you should use the jackson-datatype-hibernate, and added as their docs already explains
public class HibernateAwareObjectMapper extends ObjectMapper {
public HibernateAwareObjectMapper() {
registerModule(new Hibernate4Module());
}
}
than register
<mvc:annotation-driven>
<mvc:message-converters>
<!-- Use the HibernateAware mapper instead of the default -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="path.to.your.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
The module has a Feature.FORCE_LAZY_LOADING settings, that tells whether the object should be forced to be loaded and then serialized, which is by default set to false which I believe is the behaviour you need
Simple architectural solution is not to use model Entity as Data Transfer Object. Make Simple POJO as Data transfer Object. In the conversion logic you could easily put try and catch block for LazyInitializationException. And thus your POJO is always serializable and You can use it on your controller.
Use the #JsonIgnore annotation if you ALWAYS want to skip this particular field. use #JsonView if you want to dynamically determine which field(s) to skip. Note that #JsonView is a Jackson specific annotation, but since you're already using Jackson, things should be fine.
We can do this by adding Hibernate4Module (which support Lazy objects) to the default MappingJackson2HttpMessageConverter that Spring already provide and by adding it to HttpMessageConverters.
So we need to extend our spring config class from WebMvcConfigurerAdapter and override the method configureMessageConverters and add MappingJackson2HttpMessageConverter with the Hibernate4Module registered in it.
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Here we add our custom-configured HttpMessageConverter
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
// Here we register the Hibernate4Module into an ObjectMapper,
// then use this custom ObjectMapper
// to the MessageConverter
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
//Registering Hibernate4Module to support lazy objects
mapper.registerModule(new Hibernate4Module());
messageConverter.setObjectMapper(mapper);
return messageConverter;
}
You can solve this problem with wit 2 steps with jackson-datatype-hibernate:
kotlin example
Add In build.gradle.kts:
implementation("com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:$jacksonHibernate")
Create #Bean
#Bean
fun hibernate5Module(): Module = Hibernate5Module()
Notice that Module is com.fasterxml.jackson.databind.Module, not java.util.Module
Also good practice is to add #JsonBackReference & #JsonManagedReference to #OneToMany & #ManyToOne relationships.

What are advantages of spring DAOSupport

I read about Spring framework's DAOSupport classes. But I could not understand the advantages of these DAOSuport classes. In DAOSupport classes we call getXXXTemplate() method to get the specific template object and then use it further for DB access.
Even without extending DAOSupport we can inject XXXTemplate in our class.
Rest of this things will remain same.
Then what is advantage of extending DAOSupport class?
EDIT:- Adding example
Class extends spring's SimpleJdbcDaoSupport
public class JdbcDao extends SimpleJdbcDaoSupport {
public int create(Bb obj) {
getSimpleJdbcTemplate().update("insert into ..... ") //insert query
}
Bean of this class can be defined as :-
<bean id="jdbcDao" class="example.dao.support.JdbcDao">
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
We can create a custom class without extending SimpleJdbcDaoSupport which will have property of type JdbcTemplate
public class MyDAO {
public myJdbcTemplate; // ant its getter and setter
public int create(Bb obj) {
getMyJdbcTemplate().update("insert into ..... ") //insert query
}
It's bean wil be defined as :-
<bean id="jdbcDao" class="MyDAO">
<property name="myJdbcTemplate"><ref local="jdbcTemplateBean"/></property>
</bean>
As you can see both classes do same thing. While extending SimpleJdbcDaoSupport we are injecting DataSource and without it we are injecting directly jdbcTemplate bean. That's it. No more difference.
So I do not see any much advantage with this much use of DAOSupport classes. Any additional functionality given by DAOSupport classes ?
When you use HibernateDAOSupport you can see the difference.
1. Config the transaction to optimize the performance of the application on the applicationContext :
select : read only
create/update : read and write.
You use one session only(with getHibernateTemplate() and the sessionFactory)
When we update some data on the database we do only merge the modifications whith the method impleted on HibernateDAOSupport.
There are many method already implemented on the DAOSupport and we can use this to our need.

Spring beginner questions about annotations and thread safety

I am not sure if I am allowed to ask more than one question in a post, but here it is,
For example I have the following,
Controllers
#Controller
public class FooController{
#Autowired
private FooService fooService;
#RequestMapping(value="/foo", method=RequestMethod.POST)
public #ResponseBody foo(#RequestBody FooRequest request){
}
}
#Controller
public class BarController{
#Autowired
private FooService fooService;
#RequestMapping(value="/bar", method=RequestMethod.POST)
public #ResponseBody bar(#RequestBody FooRequest request){
}
}
Service
public class FooService{
private Foo foo;
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
public String doFoo(String str){
return foo.doFoo(str);
}
}
class to do the job
public class Foo{
public String doFoo(String str){
return (str + " is foo");
}
}
create beans using dependency injection
<context:annotation-config/>
<bean id="fooService" class="com.myapp.service.FooService">
<property name="foo" ref="foo"></property>
</bean>
<bean id="foo" class="com.myapp.foo.Foo">
</bean>
My questions are:
I did not use #service annotation at class FooService, should I use it, and why?
Is this configuration thread-safe or not, and why (how is it achieved if it is thread-safe)?
Where can I find a tutorial about the layers (dao layers, service layer ...) used in Spring design and the purpose of such a design?
You don't have to use annotations if you declare your beans in xml-config, as you did.
It is. Each bean, although a singleton, is stateless. So no concurrent modifications can occur.
For example in wikipedia. It's not spring-specific. Look for articles about three-tier architecture
Using it would simply avoid the need for declaring the bean using XML. You chose to use annotations for your other beans. I would thus also use annotations for this one.
Yes, it is, because Spring makes sure everything is properly wired up and initialized, with a synchronization barrier, before serving any request
This is a very broad question. Layering is useful for separation of concerns, testability, ability to demarcate transactions declaratively, etc.
#Repository, #Service, or #Controller (sub-annotations of #Components) are used to mark specific classes, so they can be considered more-or-less as metadata. However, there are some features of the Spring framework that can take advantage of these. One of them is automatic component scanning (a given java package will be searched for classes with the above annotations and these classes can be used as Spring beans, as if they were declared in XML). To enable this, you should put this into your spring context:
<context:component-scan base-package="my.service.package"/>
More on this can be found here: http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-classpath-scanning
Another use-case is for AOP. You can create annotation-aware pointcuts by which you can select say all your repository classes.
The Spring beans in context are brought up one by one, so there is no chance of concurrency kicking in. However, there can be circular dependencies between beans and Spring may or may not resolve this properly.
For both DAO and service stuff, the current Spring 3 documentation provides many examples and probably the best source for learning: http://static.springsource.org/spring/docs/3.0.x/reference/index.html If you'd like to have an all-round knowledge I'd recommend trying out JdbcTemplate, Rowmappers and an ORM based configuration with Hibernate.

Dynamically load spring bean properties from database or Java Objects )

I have a scenario where I need to load properties from database or java object into beans.
Consider the example:
<bean id="ConfigAsstDemoBeanParent" class="gps.springconfig.DemoClass" lazy-init="true">
<property name="demoValueFromBean" value="demoValue"></property>
<property name="demoValueForKeyFromProperties" value="${DEMO_KEY}"></property>
</bean>
and instead of the ${DEMO_KEY} property placeholder, which loads a value from the property file, I need to load a value from the database, which I retrieve using a stored procedure from a Java class.
Please suggest me a mechanism which I can leverage for the above scenario. Currently I am investigating extending SpringMain and/or PropertyPlaceholderConfigurer class and write my own custom BootStrapper.
Also please suggest hints on writing a BootStrapper for the above mentioned scenario.
One of the cases where Java configuration seems to be a great alternative:
#Configuration
public class Config {
#Resource
private DataSource dataSource;
#Bean
#Lazy
public DemoClass configAsstDemoBeanParent() {
DemoClass demo = new DemoClass();
demo.setDemoValueFromBean("demoValue");
demo.demoValueForKeyFromProperties( /* query the database here */);
return demo;
}
}
Note that you can inject DataSource (or JdbcTemplate) to your #Configuration class providing it was defined elsewhere.

Resources