Reputation: 4703
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?
Upvotes: 0
Views: 802
Reputation: 13113
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>
Upvotes: 1