mongodb DAO sets all attributes to null before save()

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

I try to receive bean of a class from context, and then save it in a mongodb collection. The problem is, all of its attributes are, for unknown reasons, set to null right before saving. It works perfectly well when I try to save objects in database created by new operator, but not with beans:

public static void main(String[] args) {     ApplicationContext ctx;     ctx = new ClassPathXmlApplicationContext("context.xml");     Komputer komputer = (Komputer)ctx.getBean("komputer");      Dao dao = (Dao)ctx.getBean(Dao.class);     dao.deleteAll();      System.out.println("inserting: " + komputer.getTyp());     dao.save(komputer); // sets everything to null and puts in db      Komputer new_komputer = new Komputer();     new_komputer.setTyp("test");      System.out.println("inserting: " + komputer.getTyp());     dao.save(new_komputer); // correctly puts in db      Iterable <Komputer> komputer_iterable = dao.findAll();     System.out.println("List: ");     for (Komputer komputer : komputer_iterable) {         System.out.println("id:" + komputer.getId() + ", typ: " + komputer.getTyp());     } } 

Result printed in console:

inserting: Intel Pentium B970 13:33:38.719 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Inserting DBObject containing fields: [_class, _id, obwodKola, liczbaLosowa] in collection: komputer 13:33:38.720 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[lab_test] inserting: test 13:33:38.726 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Inserting DBObject containing fields: [_class, _id, typ, obwodKola, liczbaLosowa] in collection: komputer 13:33:38.726 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[lab_test] 13:33:38.730 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - find using query: { } fields: null for class: class org.zut.lab1.Komputer in collection: komputer 13:33:38.731 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[lab_test] List:  id:56657ca244ae837d313d8b29, typ: null id:56657ca244ae837d313d8b2a, typ: test 

Of course, all of the first objects attributes were set correctly.

This is how dao class looks like:

import org.springframework.data.repository.CrudRepository;  public interface Dao extends CrudRepository<Komputer, String> {  } 

And also Komputer class:

import org.springframework.data.annotation.Id;  public class Komputer {     @Id     private String id;     private Procesor procesor;     private String typ;     private float obwodKola; // 2 * pi * r     private float liczbaLosowa;      public void setProcesor(Procesor procesor) {         this.procesor = procesor;     }      public Procesor getProcesor() {         return this.procesor;     }      public void setTyp(String typ) {         this.typ = typ;     }      public String getTyp() {         return this.typ;     }         public float getObwodKola() {         return obwodKola;     }      public void setObwodKola(float obwodKola) {         this.obwodKola = obwodKola;     }      public float getLiczbaLosowa() {         return liczbaLosowa;     }      public void setLiczbaLosowa(float liczbaLosowa) {         this.liczbaLosowa = liczbaLosowa;     }      public String getId() {         return id;     }      public void setId(String id) {         this.id = id;     } } 

Beans in context.xml file:

<mongo:mongo id="mongo" host="localhost" port="27017" />  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">     <constructor-arg ref="mongo" />     <constructor-arg name="databaseName" value="lab_test" /> </bean>  <mongo:repositories base-package="org.zut.lab1"></mongo:repositories>   <bean id="procesor" class="org.zut.lab1.Procesor">     <property name="iloscRdzeni" value="4"/>     <property name="czestotliwosc" value="300000"/> </bean>  <bean id="komputer" class="org.zut.lab1.Komputer">     <property name="liczbaLosowa" value="#{T(java.lang.Math).random() * procesor.czestotliwosc}"/>     <property name="procesor" ref="procesor"/>     <property name="obwodKola" value="#{T(java.lang.Math).PI * 2 * procesor.getIloscRdzeni()}"/>     <property name="typ" value="Intel Pentium B970"/> </bean> 

This makes me totally disoriented. What am I doing wrong?

回答1:

Basically, Spring AOP creates a Proxy for bean instance with id komputer.

As it proxy, it calls proxied methods (like when you mock with Mockito), but original attributes are null. If you debug your code with some IDE (Eclipse, for example), you can see what's happening.

So, when you save proxied instance, it takes attribute's value, not getters.

If you remove aop proxy from context, komputer bean will be saved correctly.

<aop:aspectj-autoproxy/> .... <aop:config>     <aop:aspect ref="profiler">         <aop:pointcut expression="execution(* org.zut.lab1.Komputer.oblicz(..)) and args(czas)"          id="test"/>         <aop:around method="profile" pointcut-ref="test"/>     </aop:aspect> </aop:config> 



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!