5

I am using JSF + Spring+ Hibernate

protected @Inject ChartOfAccount chartOfAccount;

I basically want to populate chartOfAccount from the list

for (DistributionEntry de : getDistributionEntries()) {

     chartOfAccount.setAccount(de.getAccount());
     chartOfAccountList.add(chartOfAccount);
}

for each iteration I want new object of chartOfAccount otherwise you know list contain same object with latest value.

Solution One: use new keyword :-p

for (DistributionEntry de : getDistributionEntries()) {
     ChartOfAccount coa= new ChartOfAccount();
     coa.setAccount(de.getAccount());
     chartOfAccountList.add(coa);
}

Solution Two : applicationContext.getBean

for (DistributionEntry de : getDistributionEntries()) {
     chartOfAccount= applicationContext.getBean(ChartOfAccount.class);
     chartOfAccount.setAccount(de.getAccount());
     chartOfAccountList.add(chartOfAccount);
}

But I have read the certain articles that to avoid use of applicationContext.getBean

If I avoid to use applicationContext.getBean , what is the best way to handle this type of situation ? and both behavior will same? (ApplicationContext.getBean vs new keyword )

Note: My Managed bean is @Scope("session") and Model is @Scope(BeanDefinition.SCOPE_PROTOTYPE), so as we all know that for one session it is singleton and prototype for different session.

Shahid Ghafoor
  • 2,991
  • 17
  • 68
  • 123
  • first of all, please tell me what kind of business logic encapsulated in ChartOfAccount? Are there autowired fields in object? There is difference between `new ChartOfAccount()` and `applicationContext.getBean(ChartOfAccount.class)`. In first case you create object yourself and autowired fields would be null, one the other hand if you create ChartOfAccount using application context it would be Spring Bean. Spring manage dependencies for you and inject them into ChartOfAccount instance. – Nechaev Sergey Aug 29 '15 at 15:00
  • @NechaevSergey no any business logic in ChartOfAccount, it is just a Model `@Scope(BeanDefinition.SCOPE_PROTOTYPE)public class ChartOfAccount implements Serializable {` – Shahid Ghafoor Aug 29 '15 at 15:07
  • It looks like ChartOfAccount should be POJO class. Remove bean declaration and use new keyword to create instance. As @Robert Moskal said there is common patterns where to use spring beans. Read documentation for follow up – Nechaev Sergey Aug 29 '15 at 15:15
  • How would you be able to inject a Spring managed bean using a CDI specific artifact `@Inject` (`protected @Inject ChartOfAccount chartOfAccount;`)? Obtaining a container managed instance of a Spring managed bean will require to inject that bean using the `@Autowired` annotation (or `ApplicationContext.getBean("beanName")`). Simply using the `new` operator (thus, invoking a bean's constructor on your own) will simply create a new instance of the bean which is not managed by the container in anyway. – Tiny Aug 29 '15 at 15:20
  • @Tiny I am using JSR-330 standard injection ( @ Named @ Inject ), sprint provide support for this. `@Named @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class ChartOfAccount implements Serializable {` – Shahid Ghafoor Aug 29 '15 at 15:27
  • @Tiny: wrong, check http://stackoverflow.com/questions/7142622/what-is-the-difference-between-inject-and-autowired-in-spring-framework-which – Kukeltje Aug 29 '15 at 15:31

1 Answers1

2

If your ChartOfAccount entity is on the Application Context and has injected dependencies, then an instance created with new will not get any of those injected dependencies.

The getBean() technique will get you what you want, but it is considered a bad practice in that you are hard-coding the dependency on ChartOfAccount in your code. Though with your approach and that tight loop in your code, you really don't have a choice.

If ChartOfAccount is an entity that gets persisted, it seems strange to me that you would put an instance of it on the Application Context (even with prototypical creation). The more common pattern here would be to use something like the Spring support for data access objects. Here are the docs for Hibernate:

http://docs.spring.io/spring/docs/2.0.8/reference/orm.html

Five years ago that's what you would have done. However, You might want to consider using JPA and Spring data for this: http://projects.spring.io/spring-data-jpa/. It auto-generates CRUD repositories with a lot of nice features out of the box: query generation, pagination, etc.

Robert Moskal
  • 21,737
  • 8
  • 62
  • 86
  • An instance of entity in the Application Context :If would say that why I use **new** keyword if I am using spring DI.the only reason is that I ask the spring store my entity in your bean area and I will take whenever I need . if you see the following link of mkyong , it basically declare all beans in spring beans area, and then taking from that. [mkyong.com](http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/), same way I am taking from context, if I required more object instead of new keyword. :) – Shahid Ghafoor Aug 29 '15 at 16:26
  • I think ApplicationContext.getBean considered a bad practice only when we use it with Service / DAO and I am using only with entity. Basiclly I hate to use **new** keyword with entity, Service and DAO classes :p ! And prototypical creation behavior is because I need always new instance. **Thanks for your precious response** ;) – Shahid Ghafoor Aug 30 '15 at 01:47