mongodb DAO 在 save() 之前将所有属性设置为 null [英] mongodb DAO sets all attributes to null before save()

查看:31
本文介绍了mongodb DAO 在 save() 之前将所有属性设置为 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试从上下文接收类的 bean,然后将其保存在 mongodb 集合中.问题是,由于未知原因,它的所有属性在保存之前都设置为 null.当我尝试将对象保存在由 new 运算符创建的数据库中时,它工作得非常好,但不是使用 bean:

public static void main(String[] args) {应用上下文 ctx;ctx = new ClassPathXmlApplicationContext("context.xml");Komputer komputer = (Komputer)ctx.getBean("komputer");dao dao = (Dao)ctx.getBean(Dao.class);dao.deleteAll();System.out.println("插入:" + komputer.getTyp());dao.save(电脑);//将所有内容设置为 null 并放入 dbKomputer new_komputer = new Komputer();new_komputer.setTyp("test");System.out.println("插入:" + komputer.getTyp());dao.save(new_komputer);//正确放入 db可迭代的<Komputer>komputer_iterable = dao.findAll();System.out.println("列表:");for (Komputer komputer : komputer_iterable) {System.out.println("id:" + komputer.getId() + ", typ:" + komputer.getTyp());}}

控制台打印结果:

插入:Intel Pentium B97013:33:38.719 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - 在集合中插入包含字段的 DBObject:[_class、_id、obwodKola、liczbaLosowa]:komputer13:33:38.720 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - 获取 Mongo 数据库名称=[lab_test]插入:测试13:33:38.726 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - 在集合中插入包含字段的 DBObject:[_class、_id、typ、obwodKola、liczbaLosowa]13:33:38.726 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - 获取 Mongo 数据库名称=[lab_test]13:33:38.730 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - 使用查询查找:{} 字段:空类:类 org.zut.lab1.Komputer 集合:komputer13:33:38.731 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - 获取 Mongo 数据库名称=[lab_test]列表:id:56657ca244ae837d313d8b29,类型:空id:56657ca244ae837d313d8b2a,类型:测试

当然,所有第一个对象属性都设置正确.

这就是 dao 类的样子:

import org.springframework.data.repository.CrudRepository;公共接口 Dao 扩展了 CrudRepository<Komputer, String>{}

还有电脑类:

import org.springframework.data.annotation.Id;公共类计算机{@ID私人字符串ID;私人处理器处理器;私人字符串类型;私人浮动 obwodKola;//2 * pi * r私人浮动 liczbaLosowa;公共无效setProcesor(处理器处理器){this.processor = 处理器;}公共处理器 getProcesor() {返回 this.processor;}公共无效setTyp(字符串类型){this.typ = 类型;}公共字符串 getTyp() {返回 this.typ;}公共浮动 getObwodKola() {返回obwodKola;}公共无效 setObwodKola(浮动 obwodKola){this.obwodKola = obwodKola;}公共浮动 getLiczbaLosowa() {返回 liczbaLosowa;}公共无效 setLiczbaLosowa(浮动 liczbaLosowa){this.liczbaLosowa = liczbaLosowa;}公共字符串 getId() {返回标识;}公共无效setId(字符串ID){this.id = id;}}

context.xml 文件中的 Bean:

<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>

这让我完全迷失了方向.我做错了什么?

解决方案

基本上,Spring AOP 为 id komputer 的 bean 实例创建了一个 Proxy.

作为代理,它调用代理方法(就像你用 Mockito 模拟一样),但原始属性为空.如果您使用某个 IDE(例如 Eclipse)调试代码,您可以看到发生了什么.

因此,当您保存代理实例时,它需要 attribute's 值,而不是 getters.

如果您从上下文中删除 aop proxy,komputer bean 将被正确保存.

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?

解决方案

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>

这篇关于mongodb DAO 在 save() 之前将所有属性设置为 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆