alijandro
alijandro

Reputation: 12147

hibernate one-to-one query error after insert data

I use the hibernate one-to-one mapping to build the relationship between Stock and Category. The data of Category table is imported when my web app start use the following sql statement.

insert into Category (name, created_time) values ('top', now()), ('recommend', now()), ('editor choice', now()), ('random', now());

At first, I can get the category list by execute CategoryDAOImpl.getCategories, but after execute CategoryDAOImpl.getCategorybyName(String name), the method CategoryDAOImpl.getCategories won't work, the output message show the hibernate sql execute without return.

Is there a wrong when I implemented one-to-one mapping?

How can I solve this question?

Stock.java

@Entity
public class Stock {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private long id;

    @Column(name = "name")
    private String name;

    @OneToOne
    private Category category;

    @Column(name = "created_time")
    private Date date;

    /**
     * @return the id
     */
    public long getId() {
       return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the category
     */
    public Category getCategory() {
        return category;
    }

    /**
     * @param category the category to set
     */
    public void setCategory(Category category) {
        this.category = category;
    }

    /**
     * @return the date
     */
    public Date getDate() {
        return date;
    }

    /**
     * @param date the date to set
     */
    public void setDate(Date date) {
        this.date = date;
    }

}

Category.java

@Entity
public class Category {

@Id
@GeneratedValue
@Column(name = "id")
private long id;

@Column(name = "name")
private String name;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_time")
private Date date;

@OneToOne(mappedBy = "category")
private Stock stock;

/**
 * @return the id
 */
public long getId() {
    return id;
}

/**
 * @param id the id to set
 */
public void setId(long id) {
    this.id = id;
}

/**
 * @return the name
 */
public String getName() {
    return name;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the date
 */
public Date getDate() {
    return date;
}

/**
 * @param date the date to set
 */
public void setDate(Date date) {
    this.date = date;
}

/**
 * @return the stock
 */
public Stock getStock() {
    return stock;
}

/**
 * @param stock the stock to set
 */
public void setStock(Stock stock) {
    this.stock = stock;
}

}

CategoryDAOImpl.java

@Repository
@Transactional
public class CategoryDAOImpl implements CategoryDAO {

@Autowired
private SessionFactory sessionFactory;

/*
 * (non-Javadoc)
 * 
 * @see com.example.mywebapp.dao.CategoryDAO#getCategories()
 */
@Override
public List<Category> getCategories() {
    // TODO Auto-generated method stub
    return sessionFactory.getCurrentSession()
            .createCriteria(Category.class).list();
}

/*
 * (non-Javadoc)
 * 
 * @see
 * com.example.mywebapp.dao.CategoryDAO#getCategorybyName(java.lang.String)
 */
@Override
public Category getCategorybyName(String name) {
    // TODO Auto-generated method stub
    List<Category> categories = sessionFactory.getCurrentSession()
            .createCriteria(Category.class)
            .add(Restrictions.eq("name", name)).list();
    if (categories != null && categories.size() > 0) {
        return categories.get(0);
    }
    return null;
}

/**
 * @return the sessionFactory
 */
public SessionFactory getSessionFactory() {
    return sessionFactory;
}

/**
 * @param sessionFactory
 *            the sessionFactory to set
 */
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

}

Upvotes: 1

Views: 108

Answers (1)

alijandro
alijandro

Reputation: 12147

From the debug output of hibernate, I figured out what causes the issue. When query from Category, hibernate will join the table with Stock because there is a one-to-one mapping relationship between them, so the result is not correct. By setting projections and corresponding result transformer on Category query, it works fine.

@Override
public List<Category> getCategories() {
    // TODO Auto-generated method stub
    ProjectionList projectionList = Projections.projectionList();
    projectionList.add(Projections.property("id"), "id");
    projectionList.add(Projections.property("name"), "name");
    projectionList.add(Projections.property("date"), "date");
    return sessionFactory.getCurrentSession()
            .createCriteria(Category.class).setProjection(projectionList)
            .setResultTransformer(Transformers.aliasToBean(Category.class))
            .list();
}

Upvotes: 1

Related Questions