5
\$\begingroup\$

Ι have the following database:

    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    SET time_zone = "+00:00";

    CREATE TABLE IF NOT EXISTS `Authors` (
           `AutID` int(11) NOT NULL,
            `Name` varchar(50) NOT NULL 
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;


    INSERT INTO `Authors` (`AutID`, `Name`) VALUES
    (1, 'Tolkien');

      CREATE TABLE IF NOT EXISTS `Books` (
         `BookID` int(11) NOT NULL,
         `AutID` int(11) NOT NULL,
          `Name` varchar(50) NOT NULL
          ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;


   ALTER TABLE `Authors`
    ADD PRIMARY KEY (`AutID`);

   ALTER TABLE `Books`
        ADD PRIMARY KEY (`BookID`), ADD KEY `AutID` (`AutID`);

  ALTER TABLE `Authors`
         MODIFY `AutID` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;

   ALTER TABLE `Books`
        MODIFY `BookID` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;

    ALTER TABLE `Books`
       ADD CONSTRAINT `fkautid` FOREIGN KEY (`AutID`) REFERENCES                    `Authors` (`AutID`) ON DELETE NO ACTION ON UPDATE NO ACTION;

and the following classes:

@Entity
@Table(name="Books"
,catalog="Autor"
)
public class Books  implements java.io.Serializable {


 private Integer bookId;
 private Authors authors;
 private String name;

public Books() {
}

public Books(Authors authors, String name) {
   this.authors = authors;
   this.name = name;
}

 @Id @GeneratedValue(strategy=IDENTITY)


@Column(name="BookID", unique=true, nullable=false)
public Integer getBookId() {
    return this.bookId;
}

public void setBookId(Integer bookId) {
    this.bookId = bookId;
}

@ManyToOne
@JoinColumn(name="AutID", nullable=false,insertable =  false, updatable = false)
public Authors getAuthors() {
    return this.authors;
}

public void setAuthors(Authors authors) {
    this.authors = authors;
}


@Column(name="Name", nullable=false, length=50)
public String getName() {
    return this.name;
}

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




}




@Entity   
@Table(name="Authors"
 ,catalog="Autor"
)
public class Authors  implements java.io.Serializable {


  private Integer autId;
  private String name;
  private Set<Books> bookses = new HashSet<Books>(0);

public Authors() {
}


public Authors(String name) {
    this.name = name;
}
public Authors(String name, Set<Books> bookses) {
   this.name = name;
   this.bookses = bookses;
}

 @Id @GeneratedValue(strategy=IDENTITY)


@Column(name="AutID", unique=true, nullable=false)
public Integer getAutId() {
    return this.autId;
}

public void setAutId(Integer autId) {
    this.autId = autId;
}


@Column(name="Name", nullable=false, length=50)
public String getName() {
    return this.name;
}

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

@OneToMany(fetch=FetchType.LAZY, mappedBy="authors")
public Set<Books> getBookses() {
    return this.bookses;
}

public void setBookses(Set<Books> bookses) {
    this.bookses = bookses;
}




}

I want to insert into the DB books written by Tolkien. I am doing this using the following snippet:

  public static void main(String[] args) {


    try {

        BufferedReader br=new BufferedReader(new InputStreamReader (System.in));

        System.out.println("Book Name");
        String NamesnsBook=br.readLine();


        HibernateUtil myHiber=new HibernateUtil();

        SessionFactory sessFabrika=myHiber.getSessionFactory();

        Session s = sessFabrika.openSession();
        s.beginTransaction();


        //get author
        Query q=s.createQuery("FROM Authors Where Name=:n");
        q.setParameter("n", "Tolkien");
        Authors Auth=(Authors) q.list().get(0);

        Books b=new Books();
        b.setAuthors(Auth);
        b.setName(NamesnsBook);


        s.save(b);
        s.getTransaction().commit();
        s.close();

        System.out.println("OK");

    }

    catch (Exception ex) {
        ex.printStackTrace();
    }
}

}

Is this the optimal way of inserting books of authors that already exist in the db? I mean, do I have to query the db every time in order to get the foreign key object (the Authors instance Auth in this case)?

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to CodeReview, MrRisoni. I hope you get some fine answers. \$\endgroup\$
    – Legato
    Apr 14, 2015 at 13:14

1 Answer 1

4
\$\begingroup\$

Always use singular names for entities. It's Book, not Books; and Author, not Authors.

Always get the ID. Get the surrogate key, not the business key, from the UI.

You can use Session.load to set up foreign key relations without querying the DB.

void addBook(int authorId, String bookName) {
    Session session = //...get a session

    Author author = session.load(Author.class, authorId);

    Book book = new Book(author, bookName);

    s.save(b);
}
\$\endgroup\$
3
  • \$\begingroup\$ Is it not possible to save the current object (here Book) without foreign key object (here Author). Something like, I have the author_id and bookName... I want to save the Book object by setting these two elements alone. \$\endgroup\$
    – subbu
    Dec 17, 2015 at 9:24
  • \$\begingroup\$ @subbu Why would you want to do that? If you do that, it leads to mangled code. And if your model requires you write mangled code, you should change your model. Also as seen here Session.load. does not hit DB unless necessary, and you would want to hit DB when necessary. so what's wrong with Session.load \$\endgroup\$ Dec 17, 2015 at 9:49
  • \$\begingroup\$ Thanks for the info. Yes, Session.load() solves my problem. Just to avoid a DB hit. I was just curious to know if there is any substitute for the old traditional approach where we just do the insertion of the Book object with authorId alone without actually loading the object. \$\endgroup\$
    – subbu
    Dec 18, 2015 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.