Announcement Announcement Module
Collapse
No announcement yet.
findById returns null Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • findById returns null

    1.
    Code:
    PostThread thread = op.findOne(new Query(new Criteria("_id").is(id)), PostThread.class);
    2.
    Code:
    PostThread thread = op.findById(id, PostThread.class);
    statement 1 returns object.
    statement 2 returns null.

    What's the problem ?

    my domain class is

    Code:
    @Document
    public class PostThread {
    
    	@Id
    	private int id;
    
    	private int categoryId;
    }

  • #2
    Hi,

    It is probably related to your other question regarding to using int as an @Id value. This section of the docs (How the '_id' field is handled in the mapping layer) goes over the conventions in terms of what is supported with using and Id field an generated values.

    I presume in your case you were expecting the id field to be populated after a save. That will only work if the id field is of the type String, BigInteger or ObjectId. Those are the only types in which the automatically generated Mongo OID can be marshalled into. You can store an int value as the mongo _id value but you would need to assign it in the POJO first before saving.

    So, either change your Id type to be String, BigInteger or ObjectId in the PostThread class or assign the id yourself before saving. We will change the code so than if an @Id field other than String,BigInteger, or ObjectId is passed to MongoTemplate for a save and it has a null value, an exception will be thrown. See this issue.

    Here is some working code

    Code:
    	PostThread pt = new PostThread();
    		pt.setCategoryId(1);
    		template.save(pt);
    		String id = pt.getId();
    		PostThread thread = template.findById(id, PostThread.class);
    		assertNotNull(thread);
    		System.out.println(thread);
    		thread = template.findOne(query(where("id").is(id)), PostThread.class);
    		assertNotNull(thread);
    		System.out.println(thread);
    And PostThread is
    Code:
    public class PostThread {
    	@Override
    	public String toString() {
    		return "PostThread [id=" + id + ", categoryId=" + categoryId + "]";
    	}
    
    	private String id;
    	
    	private int categoryId;
    
    	public String getId() {
    		return id;
    	}
    
    	public void setId(String id) {
    		this.id = id;
    	}
    
    	public int getCategoryId() {
    		return categoryId;
    	}
    
    	public void setCategoryId(int categoryId) {
    		this.categoryId = categoryId;
    	}
    	
    }
    Note that in this case, since it is such a simple class, you don't even need to use the Spring mapping annotations.

    Cheers,
    Mark
    Last edited by Mark Pollack; Nov 17th, 2011, 11:21 AM.

    Comment


    • #3
      Thank you for reply.
      But i'm generating int id value manually.

      Code:
      public class Seq {
      
      	@Autowired
      	private MongoOperations op;
      
      	private int threadId;
      	private int postId;
      
      	@PostConstruct
      	private void init() {
      		threadId = getThreadSeed();
      		postId = getPostSeed();
      	}
      
      	private int getThreadSeed() {
      		Query query = new Query();
      		query.sort().on("_id", Order.DESCENDING);
      		query.limit(1);
      		List<PostThread> threadList = op.find(query, PostThread.class);
      		return threadList.isEmpty() ? 0 : threadList.get(0).getId();
      	}
      
      	private int getPostSeed() {
      		Query query = new Query();
      		query.sort().on("_id", Order.DESCENDING);
      		query.limit(1);
      		List<Post> postList = op.find(query, Post.class);
      		return postList.isEmpty() ? 0 : postList.get(0).getId();
      	}
      
      	public synchronized int getNewThreadId() {
      		return ++threadId;
      	}
      
      	public synchronized int getNewPostId() {
      		return ++postId;
      	}
      }
      and assigns id before insert.

      Code:
      	public void insertThread(PostThread thread) {
      		thread.setId(seq.getNewThreadId());
      		op.insert(thread);
      	}
      If int id is set as 10 and saved, it goes as "10" not as 10.
      then
      If I call findById(10), it returns null,
      If I call findOne(new Query(new Criteria("_id").is(10)), PostThread.class), it returns null.

      then I modify "10" to 10 manually,

      and
      If I call findById(10), it returns null,
      If I call findOne(new Query(new Criteria("_id").is(10)), PostThread.class), it returns as normal.

      Comment

      Working...
      X