spring4 beans injection in bean constructor using #Autowired - spring

I have Class object constructor where one of parameters is Long parent_id cause object is self related as follow:
public class Folder {
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Folder parent;
}
When I try to deserialize with Gson I have to create object using Gson. Using parent_id I would like to creat new object of Folder to apply it to parent element.
When I try to do:
#Transient #Autowired public Folder folderDao;
someMethod() {
folderDao.get(9L);
}
My dao class:
#Override
public T get(Long id) {
System.out.println("_Trying to get by id...");
return (T) getCurrentSession().get(entityClass, id);
}
I got a NullPointerException
and this line is not excecuted: System.out.println("_Trying to get by id...");
I dont know why. Can anyone help me? What Am I doing wrong with Spring Injection.
By the way: My controllers have #Transactional annotation

Seems that skeletonElementDao is null.
Should you autowire the dao, not the folder?
#Autowired
private SkeletonElementDao skeletonElementDao;
instead of
#Transient #Autowired public Folder folder;

Related

Spring constructor injection using java config

I have a Class that accepts the following constructor
public Student(int id, String name, Map<String, List<String>> mapInject) {
super();
this.id = id;
this.name = name;
this.mapInject = mapInject;
}
And from spring Java Config, I am injecting the constructor args like below..
#Configuration
public class JavaConfig {
#Bean
public Employee getEmployeeBean() {
Map<String,List<String>> mapInject = new HashMap<String,List<String>>();
//Add map element
return new Employee(3123,"John",mapInject);
}
}
Am i doing constructor injection here? Is this the right way to do so?
I wouldn't use Spring to handle this bean creation, unless you want ALL employees to have the same id and name which I doubt.
The power behind Spring is its Dependency Injection (DI) where you define beans for providers such as database managers, services, etc. and inject those into your components. Defining a #Bean like you have there serves no purpose as now you can only inject employees with an id of 3123 and name John.
It's important to understand that just because you are using Spring it doesn't mean EVERYTHING needs to be handled as a bean - you will always need standard POJOs for housing and passing around state (such as your Employee class) which doesn't need to have anything to do with Spring.
Down the line you might have an EmployeeService for example which houses business logic to fetch employees from a database or something, this could then be configured as a bean so it can be injected across the application.
EDIT
#Configuration
public class JavaConfig {
#Bean
#Autowired //assuming a sessionfactory been is configured elsewhere
public EmployeeService employeeService(final SessionFactory sessionfactory) {
return new EmployeeService(sessionFactory);
}
}
You could then inject this anywhere (maybe in a controller for example):
#RestController
public class EmployeeController {
private final EmployeeService employeeService;
#Autowired
public EmployeeController(final EmployeeService employeeService) {
this.employeeService = employeeService;
}
}
Where the EmployeeController doesn't need to know or care that the userService has a DB connection and doesn't need to worry about configuring it as Spring will handle all of that.

Spring: autowired service in a component is null

I have created a service:
package tn.ett.medial.service;
#Service
public class ExchangeService {
private Currency EURCurrency;
public Currency getEURCurrency() {
....
return EURCurrency;
}
and a component
package tn.ett.medial.utils.dto;
#Component
public class ProductDTO implements Serializable {
#Autowired
ExchangeService exchangeService;
public ProductDTO() {
}
public ProductDTO(Product product){
System.out.println("service****" + exchangeService);
Currency EURCurrency = exchangeService.getEURCurrency();
}
}
I added the component-scan tag in my application context
<context:component-scan base-package="tn.ett.medial" />
Why the exchangeService is null? (although it works when I inject it into a #Controller).
Since this is a DTO, I guess you do something like ProductDTO productDTO = new ProductDTO();.
So annotated #Autowired ExchangeService is null because Spring doesn't know about the copy of ProductDTO that you created with new and didn't know to autowire it.
Some more info
You run this code:
System.out.println("service****" + exchangeService);
Currency EURCurrency = exchangeService.getEURCurrency();
in a constructor, that is not autowired. No wonder it can not autowire bean, since it is not a bean itself.
The idea of IoC is that Spring Container is creating beans itself.
If you want Spring to use a specific constructor, you have to Autowire it like this:
package tn.ett.medial.utils.dto;
#Component
public class ProductDTO implements Serializable {
private final ExchangeService exchangeService;
public ProductDTO() {
}
#Autowired
public ProductDTO(Product product, ExchangeService exchangeService){
this.exchangeService = exchangeService;
System.out.println("service****" + exchangeService);
Currency EURCurrency = exchangeService.getEURCurrency();
}
}

What is the proper way for fetching or ignoring lazy loaded objects using hibernate and spring

I am using spring MVC + hibernate + jackson.
Spring version : 4.3.x
Hibernate version : 4.3.x
I want to create two API- one fetching BeanB objects as well while one not fetching BeanB object. I am using fetchtype.lazy for the same.
I have following beans:
#Entity
class BeanA
{
#Id
int id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "BeanB_id")
private BeanB beanB;
//getters and setters
}
#Entity
class BeanB
{
#Id
int i;
//getters and setters
}
In my controller I have two methods: (Removing service layer to make question small. In my service layer class, I have #Transactional)
#RequestMapping(value = "/beanA/{id}" , method=RequestMethod.GET)
public ResponseEntity<BeanA> findDetailedBeanAById(#PathVariable("id") int id )
{
// to return beanA object with beanB
BeanA beanA = beanADao.findDetailedBeanAById(id);
return new ResponseEntity<BeanA>(beanA, HttpStatus.OK);
}
#RequestMapping(value = "/beanA/{id}" , method=RequestMethod.GET)
public ResponseEntity<BeanA> findNonDetailedBeanAById(#PathVariable("id") int id )
{
// to return beanA object without beanB
BeanA beanA = beanADao.findNonDetailedBeanAById(id);
return new ResponseEntity<BeanA>(beanA, HttpStatus.OK);
}
In My Dao
public BeanA findDetailedBeanAById(long id) {
BeanA beanA = (BeanA) getSession().get(BeanA.class, id);
Hibernate.initialize(beanA.getBeanB())
return beanA;
}
public BeanA findNonDetailedBeanAById(long id) {
BeanA beanA = (BeanA) getSession().get(BeanA.class, id);
return beanA;
}
When I am hitting findNonDetailedBeanAById controller method, I am getting error as :
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not initialize proxy - no Session
When I am hitting findNonDetailedBeanAById controller method, I am getting error as :
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)`
What changes are needed to be done?
For the detailed findBy method you can build a custom query and fetching the beanB inside of the query, like getSession().createQuery("SELECT a FROM beanA a LEFT JOIN FETCH a.beanB WHERE a.id == :id")
For the lazy findBy method I think you need to add the #Transactional(readonly=true) at the controller level, because you are trying to use the beanA after getting it with the service which was annotated as transactional. I think it tries to fetch the beanB from the database but the hibernate session might already be closed.
I was not able to tryout any of my suggestions because I'm only at phone.

Spring autowired using constructor

I want to create a object using few properties, how can I achieve that using Spring #Autowired ?
E.g.-
public class Person{
private String fname;
private String lname;
public Person(String fname, String lname){
this.fname = fname;
this.lname = lname;
}
}
How can I create a object using #Autowired of Person class by passing these properties at runtime.
Atul
Do you really want to autowire the variables? Or do you want to set them explictly when getting the bean?
In the later case, you can simply call ApplicationContext.getBean(Class<T> clz, Object ... arguments), in your case...
Person person = context.getBean(Person.class, "Henry", "Miller");
Obviously that doesn't have anything to do with #Autowired. Or do you want to autowire some strings into it? In that case you normally would use the #Value annotation. Autowired is used to inject beans, which you can do via field injection...
#Autowired
private MyService service;
...via constructor injection...
#Autowired
public Person(MyService service) { ... }
...via setter injection...
#Autowired
public void setMyService(MyService service) {..}
But normally you only autowire beans that way. Strings are no beans, so you have to use #Value...
#Autowired
public Person(#Value('${app.some.property}') final String firstName) {...}
This would inject the configured property of app.some.property into that bean. Of course, this only is good if you actually want to inject something from the application context. If you want to create the Person dynamically, you can use the method above.

#Autowired in Spring MVC #Controller does not work on a private field

I have a Spring MVC Controller in a very XML-slimmed application, we use a lot of annotations and as little config as possible. The Controller is working and it also has a number of resource values injected. But I've experienced a really strange behavior with this controller; annotated private fields referencing other components will not be injected.
This will not work.
#Controller
public class EntranceUnitController {
#Value("${remote.baseUrl}")
private String baseUrl = "http://localhost";
#Value("${remote.port}")
private String pushPort = "8080";
#Autowired
private HttpClientFactory httpClientFactory;
...
It seems that the httpClientFactory isn't there yet when the private fields are set, if I set a break point to inspect the value there is of course null set when the controller is created.
BUT, if I make a setter for the component and annotate the set-method instead of the private field the controller works as expected.
#Controller
public class EntranceUnitController {
#Value("${remote.baseUrl}")
private String baseUrl = "http://localhost";
#Value("${remote.port}")
private String pushPort = "8080";
private HttpClientFactory httpClientFactory;
#Autowired
public void setHttpClientFactory(HttpClientFactory httpClientFactory) {
this.httpClientFactory = httpClientFactory;
}
...
To me this is really annoying. Isn't the auto wiring injection for annotated values happening at the same time regardless injection point? I.e. why does it matter that the object is injected with a setter? I thought that private field injections are directly followed by constructs and setters, me start to think I'm wrong in that case...
Seems like your dependencies are in fact injected, you are just putting a breakpoint in the wrong moment (too early) and the dependencies aren't injected yet, despite class being already created.
Remember that, unless you are using constructor injection, the first place where you can use injected dependencies is #PostConstruct method:
#Controller
public class EntranceUnitController {
#Autowired
private HttpClientFactory httpClientFactory;
#PostConstruct
public void init() {
httpClientFactory //should not be null
}

Resources