2016-07-20 8 views
2

MongoDBとRestコントローラを使用してspringbootアプリケーションを作成し、OneToManyなどの古典的なJpaアノテーションの代わりにDBRefを使用してオブジェクトを一緒に接続しようとしています。目的は特定のアカウントのすべてのブックマークを印刷することです。ブックマークのリストはユーザー名で見つかりますが、動作しないようです。spongbootでmongoDBを使ってエンティティ間のリレーショナルマッピングを作成する方法は?

これらは私のクラスである:

@Document 
public class Account { 
    @DBRef 
    private Set<Bookmark> bookmarkSet = new HashSet<>(); 

    @Id 
    private String id; 

    @JsonIgnore 
    private String username; 
    private String password; 

    public Account(String username, String password) { 
     this.username = username; 
     this.password = password; 
    } 

    public void setBookmarkSet(Set<Bookmark> bookmarkSet) { 
     this.bookmarkSet = bookmarkSet; 
    } 

    public String getId() { 
     return id; 
    } 
} 

@Document 
public class Bookmark { 

    @DBRef 
    @JsonIgnore 
    private Account account; 

    @Id 
    private String id; 

    private String uri; 
    private String description; 

    public Bookmark(Account account, String uri, String description) { 
     this.account = account; 
     this.uri = uri; 
     this.description = description; 
    } 

    public Account getAccount() { 
     return account; 
    } 

    public String getId() { 
     return id; 
    } 

    public String getUri() { 
     return uri; 
    } 

    public String getDescription() { 
     return description; 
    } 
} 

リポジトリ:

public interface AccountRepository extends MongoRepository<Account, Long> { 
    Optional<Account> findOneByUsername(String username); 
} 

public interface BookmarkRepository extends MongoRepository<Bookmark, Long> { 
    Collection<Bookmark> findByAccountUsername(String username); 
} 

そしてRestController:

@RestController 
@RequestMapping("/{userId}/bookmarks") 
public class BookmarkRestController { 
    private final AccountRepository accountRepository; 
    private final BookmarkRepository bookmarkRepository; 

    @Autowired 
    public BookmarkRestController(AccountRepository accountRepository, BookmarkRepository bookmarkRepository) { 
     this.accountRepository = accountRepository; 
     this.bookmarkRepository = bookmarkRepository; 
    } 

    @RequestMapping(value = "/{bookmarkId}", method = RequestMethod.GET) 
    Bookmark readBookmark(@PathVariable String userId, @PathVariable Long bookmarkId) { 
     this.validateUser(userId); 
     return bookmarkRepository.findOne(bookmarkId); 
    } 

    @RequestMapping(method = RequestMethod.GET) 
    Collection<Bookmark> readBookmarks(@PathVariable String userId) { 
     this.validateUser(userId); 
     return this.bookmarkRepository.findByAccountUsername(userId); 
    } 

    private void validateUser(String userId) { 
     this.accountRepository.findOneByUsername(userId).orElseThrow(() -> new UserNotFoundException(userId)); 
    } 
} 

私は、アプリケーションを実行した後、私はこのエラーを取得する:

Invalid path reference account.username! Associations can only be pointed to directly or via their id property! 

答えて

1

あなたは正しいスキーマデザインを持っているかどうかはわかりません。リレーショナルデータベース型モデルに基づいてオブジェクトをモデル化したと仮定します。ここでは、データは正規化され、データは複数のテーブルに分割され、IDを使用して関係が取得されます。 MongoDBを使用すると、1つのドキュメントに含まれている階層構造でデータを構造化して格納することができます。

あなたの例では、ブックマークはドキュメント自体ではなく、アカウントのサブドキュメントになります。ブックマークオブジェクトから@Documentアノテーションを削除し、@DBRef注釈を削除し、ブックマークをアカウント文書内に保存するだけです。

これは、より多くのこのようなあなたのスキーマを与えるだろう:

{ 
    "_id": 1, 
    "bookmarkSet": [ 
    { 
     "uri": "http://www.foo.com", 
     "description": "foo" 
    }, 
    { 
     "uri": "http://www.bar.com", 
     "description": "bar" 
    } 
    ], 
    "username": "John", 
    "password": "password" 
} 

*注:ブックマークサブ文書を作成する場合は、ブックマークオブジェクト

最高のデザインが異なりますから_idメンバーを削除することができます各勘定科目が持つと思われるブックマークの数。唯一のほんの少しのブックマークなら、私が提案したことはうまくいくでしょう。あなたが何千というものを持っているなら、あなたはそれを異なって構造化したいかもしれません。 NoSQLデータベースには、スキーマ設計に関する記事がたくさんあります。これは、サブ文書を非常にうまく埋め込むためのオプションをカバーしています: http://blog.mongodb.org/post/87200945828/6-rules-of-thumb-for-mongodb-schema-design-part-1

+0

しかし、私は1000のブッ​​クマークがある場合、それらを保存する方法は、手動で格納することは狂っています。私はAutowireを使うべきですか?どのくらい正確に? – Gustavo

+0

私は自分の答えを更新しました。乾杯 – robjwilkins

関連する問題