简体   繁体   中英

Serialize two objects with many-to-many relationship in java

I have class "Book" and class "Author" in Java.There is many-to-many relationship between Book and Author.

Book Class :

public class Book
{
    int ISPN;
    String title;
    String description;
    int pageCount;
    public ArrayList<Author> Authors;
}

Author Class :

public class Author 
{
    int authorID;
    String firstName;
    String lastName;
    ArrayList<Book> books;
}

I want to serialize an object of Book or Author, but there will be an infinite recursion, as every Book has a list of his associated authors, who have their associated books, etc to infinity. So how to handle situations like this ?

Sorry for my bad English.

As far as you have many-to-many relationship you need to have some storage in order to store all data (something like database). And the best approach IMHO is make you lists transient and restore items from this storage when you are restoring your serialisable. If it is really database in your case you can use some in-memory cache in order to make it faster.

[EDIT]:

Here is alternative implementation with storage:

Storage.java :

public class Storage implements Serializable {
    private final HashMap<Integer, Book> books;
    private final HashMap<Integer, Author> authors;

    public Storage() {
        books = new HashMap<>();
        authors = new HashMap<>();
    }

    public void addBook(Book book) {
        books.put(book.ISPN, book);
    }

    public void removeBook(Book book) {
        books.remove(book.ISPN);
    }

    public void addAuthor(Author author) {
        authors.put(author.authorID, author);
    }

    public void removeAuthor(Author author) {
        authors.remove(author.authorID);
    }

    public Author getAuthor(Integer authorId) {
        return authors.get(authorId);
    }

    public Book getBook(Integer bookId) {
        return books.get(bookId);
    }
}

Book.java :

public class Book implements Serializable {
    int ISPN;
    String title;
    String description;
    int pageCount;
    ArrayList<Integer> AuthorIds;
    Storage storage;

    public Book(Storage storage) {
        this.storage = storage;
    }

    public void addAuthor(Author author) {
        storage.addAuthor(author);
        AuthorIds.add(author.authorID);
    }

    public List<Author> createAuthorsList() {
        List<Author> authorList = new ArrayList<>();
        for (Integer authorId : AuthorIds) {
            authorList.add(storage.getAuthor(authorId));
        }
        return authorList;
    }
}

Author.java :

public class Author {
    int authorID;
    String firstName;
    String lastName;
    ArrayList<Integer> bookIds;
    Storage storage;

    public Author(Storage storage) {
        this.storage = storage;
    }

    public void addBook(Book book) {
        storage.addBook(book);
        bookIds.add(book.ISPN);
    }

    public List<Book> createBooksList() {
        List<Book> bookList = new ArrayList<>();
        for (Integer bookId : bookIds) {
            bookList.add(storage.getBook(bookId));
        }
        return bookList;
    }
}

The only one (but big) disadvantage of using this implementation, that after deserialisation you will have multiple instances of Storage class with same data. It order to optimize this I would suggest you to make storage entries as transient members and serialize them separately.

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