简体   繁体   中英

mongodb spring data save

I'm quite new to MongoDB and Spring Data, I'm doing some code to improve my skills.

I think I'm doing all right, but I have a problem (a strange one).

I've a small example, let me say instead of classic Hello Word, I'm coding a small expense report tool.

This is the TestMain App

package com.jaex.model;

import java.util.ArrayList;
import java.util.Currency;
import java.util.Date;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

import com.jaex.repositories.ExpenseCategoryRepository;
import com.jaex.repositories.ExpenseRepository;
import com.jaex.repositories.ProjectRepository;
import com.jaex.repositories.UserRepository;



public class Main {


    public static void main(String[] args) {
        ApplicationContext ctx = new GenericXmlApplicationContext("spring-config.xml");



        ExpenseCategoryRepository ur = (ExpenseCategoryRepository) ctx.getBean("expenseCategoryRepository");
        ExpenseRepository ur1 = (ExpenseRepository) ctx.getBean("expenseRepository");
        UserRepository userrepo = (UserRepository) ctx.getBean("userRepository");
        ProjectRepository prjRepo = (ProjectRepository) ctx.getBean("projectRepository");


        Project p = prjRepo.findByProjectId("123456");
        if (p == null) {
            p = new Project("123456", "The Project", true, new Date());
            p = prjRepo.save(p);
        }


        ExpenseCategory c1 = ur.findByName("Dinner");
        if (c1 == null) {
            c1 = new ExpenseCategory("Dinner", "");
            c1 = ur.save(c1);
        }


        User user = userrepo.findByUserId("freeman");
        if (user == null) {
            user = new User("freeman");
            user.setLastName("Doe");
            user.setFirstName("J.");

            user  = userrepo.save(user);

        }

        List<ExpenseReport> a = new ArrayList<ExpenseReport>();
        for (int i = 0; i < 10; i++) {
            ExpenseReport er  = new ExpenseReport();
            er.setExpenseNumber("ER" + System.currentTimeMillis());
            er.setComment("a comment");
            er.setName("a name");
            er.setSubmittedBy(user);


            List<ExpenseEntry> list = new ArrayList<ExpenseEntry>();

            double amount = (Math.random()) + Math.random();

            list.add(new ExpenseEntry(p.toLite(),  amount, Currency.getInstance("EUR"), c1.toLite()));

            er.addToTotal(amount);

            amount = (Math.random()) + Math.random();

            list.add(new ExpenseEntry(p.toLite(),  amount,Currency.getInstance("USD"), c1.toLite()));
            er.addToTotal(amount);

            amount = (Math.random()) + Math.random();

            list.add(new ExpenseEntry(p.toLite(),  amount,Currency.getInstance("USD"), c1.toLite()));
            er.addToTotal(amount);


            er.setExpenses(list);


            a.add(er);      


        }

        try {

            ur1.save(a);
        } catch (Throwable t) {
            System.err.println(t.getMessage());
        }

        System.out.println(ur1.count());

    }

}

As you can see I'm doing a small "for" just to put some data inside.

The issue is that anyway I got just one record every Main execution. (this was an improved with the old mongodb I just got ONE record, no way to put more than one)

this is the Expense class

package com.jaex.model;

import java.io.Serializable;
import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

    @Document(collection = "ExpenseReports")
    public class ExpenseReport implements Serializable {


    private static final long serialVersionUID = 2244814936573280668L;

    @Id
    private ObjectId id;

    @Indexed(unique = true)
    private String expenseNumber;

    private String name;
    private String comment;

    private double total;


    private User submittedBy;


    private List<ExpenseEntry> expenses;


    public ExpenseReport() {
        this.total = 0;
    }


    public String getExpenseNumber() {
        return expenseNumber;
    }


    public void setExpenseNumber(String expenseNumber) {
        this.expenseNumber = expenseNumber;
    }

    public String getName() {
        return name;
    }


    public String getComment() {
        return comment;
    }


    public User getSubmittedBy() {
        return submittedBy;
    }


    public List<ExpenseEntry> getExpenses() {
        return expenses;
    }



    public void setName(String name) {
        this.name = name;
    }


    public void setComment(String comment) {
        this.comment = comment;
    }


    public void setSubmittedBy(User submittedBy) {
        this.submittedBy = submittedBy;
    }


    public void setExpenses(List<ExpenseEntry> expenses) {
        this.expenses = expenses;
    }


    @Override
    public String toString() {
        return String.format("ExpenseReport [id= %s, expenseNumber=%s, name=%s, comment=%s, submittedBy=%s, expenses=%s]",
                getId(), expenseNumber, name, comment, submittedBy, expenses);
    }


    public double getTotal() {
        return total;
    }


    public void setTotal(double total) {
        this.total = total;
    }

    public void addToTotal(double total) {
        this.total = this.total + total;
    }


    public ObjectId getId() {
        return id;
    }


    public void setId(ObjectId id) {
        this.id = id;
    }




}

All repositories

extends CrudRepository<T, ObjectId>

JDK: 1.8

MongoDB: MongoDB shell version: 3.2.4

Spring data: 1.9.1.RELEASE (org.springframework.data/spring-data-mongodb)

Any help? Got it! The issue is not with ER class but with User.

If I use the Indexed annotation doesn't work, without works.

Now I've two questions:

  1. Why there is no exception ?
  2. The user if you have a look at the main, is just inserted one time, then used over and over.... so where is my error?

Below the code class

package com.jaex.model;

import java.io.Serializable;

import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.IndexDirection;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document (collection  = "Users")
public class User implements Serializable, Comparable<User>{
    private static final long serialVersionUID = 990052324161479791L;

    @Id
    private ObjectId id;

    @Indexed(unique = true, direction = IndexDirection.ASCENDING, useGeneratedName = true)
    private String userId;

    private String firstName;
    private String lastName;



    public User() {

    }

    public User(String userId) {
        this.userId = userId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public int compareTo(User o) {
        return o.getUserId().compareTo(userId);
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((userId == null) ? 0 : userId.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (userId == null) {
            if (other.userId != null)
                return false;
        } else if (!userId.equals(other.userId))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return String.format("User [userId=%s]", userId);
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }



}

Thanks

setExpenseNumber in your forloop uses System.currentTimeInMillis which is still so fast that it could probably have the same ER number for the whole list and your document expects unique expenseNumber. Why not try to use the index i as suffix to be sure its unique and check if this works?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM