2016-10-20 7 views
2

Почему Hibernate обнаруживает нулевые значения, когда я пытаюсь добавить новый объект? У меня есть класс Product, у которого есть полевой объект Category. Категория в продукте хранится в базе данных как category_id. Вот мой класс Product.Почему я получаю нулевое значение? (HIBERNATE, SPRING)

@Entity 
@Table(name = "PRODUCT") 
public class Product implements java.io.Serializable { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

private long id; 

private String upc; 

private Category category; 

private String name; 

private String description; 

private BigDecimal price; 

public Product(){ 

} 

public Product(String upc){ 
    this.upc = upc; 
} 

public Product(String upc, String name, BigDecimal price){ 
    this.upc = upc; 
    this.name = name; 
    this.price = price; 
} 

public Product(String upc, Category category, String name, String description, BigDecimal price) { 
    super(); 
    this.upc = upc; 
    this.category = category; 
    this.name = name; 
    this.description = description; 
    this.price = price; 
} 

public void setId(long id) { 
    this.id = id; 
} 

@Id @GeneratedValue 
@Column(name = "id") 
public long getId() { 
    return id; 
} 

@Column(name = "upc", nullable = false) 
public String getUpc() { 
    return upc; 
} 

public void setUpc(String upc) { 
    this.upc = upc; 
} 

@ManyToOne @NotNull 
@JoinColumn(name = "category_id", referencedColumnName = "category_id") 
public Category getCategory() { 
    return category; 
} 

public void setCategory(Category category) { 
    this.category = category; 
} 

@Column(name = "name") 
public String getName() { 
    return name; 
} 

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

@Column(name = "description") 
public String getDescription() { 
    return description; 
} 

public void setDescription(String description) { 
    this.description = description; 
} 

@Column(name = "price") 
public BigDecimal getPrice() { 
    return price; 
} 

public void setPrice(BigDecimal price) { 
    this.price = price; 
} 
} 

А вот моя Категория класс:

@Entity 
@Table(name = "CATEGORY") 
public class Category implements Serializable{ 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

private long id; 
private String categoryId; 
private String name; 
private Set<Product> products; 

public Category(){} 

public Category(String categoryId, String name) { 
    super(); 
    this.categoryId = categoryId; 
    this.name = name; 
} 

public void setId(long id) { 
    this.id = id; 
} 

@Id @GeneratedValue 
@Column(name = "id") 
public long getId() { 
    return id; 
} 

@Column(name = "category_id") 
public String getCategoryId() { 
    return categoryId; 
} 

public void setCategoryId(String categoryId) { 
    this.categoryId = categoryId; 
} 

@Column(name = "name") 
public String getName() { 
    return name; 
} 

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

@OneToMany 
@JoinColumn(name = "category_id", insertable = false, updatable = false) 
public Set<Product> getProducts() { 
    return products; 
} 

public void setProducts(Set<Product> products) { 
    this.products = products; 
} 
} 

Теперь, когда я использую метод session.save (продукт), он получает нулевое значение в поле Категории, но при использовании родной SQL в бегах отлично. Я попытался напечатать идентификатор категории и его там. Вот мой код для добавления продукта:

@Override 
public void addProduct(Product product) { 

    System.out.println(product.getCategory().getCategoryId()); 

    Session session = sessionFactory.openSession(); 

    Transaction transaction = null; 

    try { 
     transaction = session.beginTransaction(); 

//   Query query = session.createSQLQuery(DAOQuery.HQL_ADD_PRODUCT).setParameter("upc", product.getUpc()) 
//        .setParameter("category", product.getCategory().getCategoryId()) 
//        .setParameter("name", product.getName()).setParameter("description", product.getDescription()) 
//        .setParameter("price", product.getPrice()); 
// 
//   query.executeUpdate(); 
     session.save(product); 

     transaction.commit(); 
    } catch (HibernateException e) { 
     if (transaction != null) 
      transaction.rollback(); 

     e.printStackTrace(); 
    } finally { 
     session.close(); 
    } 
} 

Здесь ошибка:

WARN: SQL Error: 1048, SQLState: 23000 
Oct 20, 2016 8:30:15 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 
ERROR: Column 'category_id' cannot be null 
org.hibernate.exception.ConstraintViolationException: could not execute statement 
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) 
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207) 
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57) 
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42) 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2840) 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3411) 
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81) 
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:597) 
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:232) 
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:213) 
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:256) 
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318) 
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275) 
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182) 
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113) 
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192) 
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38) 
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177) 
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32) 
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73) 
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:667) 
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:659) 
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:654) 
at com.qbryx.dao.ProductDaoHQLImpl.addProduct(ProductDaoHQLImpl.java:138) 
at com.qbryx.service.ManagerServiceImpl.addProduct(ManagerServiceImpl.java:24) 
at com.qbryx.controller.ManagementController.createProduct(ManagementController.java:62) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:180) 
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440) 
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Unknown Source) 
Caused by: java.sql.SQLException: Column 'category_id' cannot be null 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1600) 
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1129) 
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:681) 
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1368) 
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1283) 
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1268) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204) 
... 63 more 

Я не могу показаться, чтобы найти то, что это не так. Мне нужна помощь. Благодарю.

+1

вы установить проверку '@ NotNull' в атрибуте категории –

ответ

3

Ошибка говорит о том, что categoryId имеет значение null, а ваша база данных не имеет значения null.

Вы отметили id с @Id @GeneratedValue и Hibernate сгенерировали для этого новое длинное значение, но если вы не указали значение для categoryId, оно не будет сгенерировано.

Вы должны либо переместить @Id @GeneratedValue в categoryId, либо указать значение при его создании.

Кроме того, я предлагаю вам ознакомиться с вашим дизайном, потому что это смущает наличие в вашем классе id и categoryId; в конце дня все будут ссылаться на имущество id как «id категории», и вы не будете знать, ссылаются ли они на этот идентификатор или на «categoryId».

0

Вы не указали правильную стратегию для . генерируя Id для категории

Если база данных использует последовательности, можно сопоставить идентификатор, как:

@GeneratedValue(strategy = GenerationType.IDENTITY) 

Или создать поколение stragedy, если он не

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "category_generator") 
@SequenceGenerator(name="category_generator", sequenceName = "category_seq") 
Смежные вопросы