dear developers.
I'm going to ask you a question which I think hard to solve for me just because I don't know the basic why to answer, what I mean?? Let's see. The associations in JBoss documentations did not get the comprehensive answer: Why I should use JoinTable instead of Foreign Key and I do not completely understand how mappings works, What do I mean by this? I know what is association are ManyToMany or ManyToOne etc. and for what aims they are, but how they work's and collaborate with each other don't need an answer about bi-directional or unidirectional or joinTable or associations, I would like to have the link where I can find full info about my two questions:
1) Why I should use JoinTable instead of Foreign Key????
2) how entity work's and collaborate with each other(without explanations what is manyToMany etc. associations and bi or unidirectional associations are)???
So, I have piece of code where I stuck because misunderstanding, I'm just trying to insert data I'm MYSQL database: Name_INSTITUTION and TYPE_NAME(Type of institution):*
My entity class:
@Entity
@Table(name="INSTITUTION")
public class Institution implements Serializable{
private static final long serialVersionUID = -7636394097858726922L;
private int Id;
@Id
@GeneratedValue(strategy=IDENTITY)
@Column(name="ID")
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
private int Version;
@javax.persistence.Version
@Column(name="VERSION")
public int getVersion() {
return Version;
}
public void setVersion(int version) {
Version = version;
}
private String Name_Institution;
@Column(name="NAME_INSTITUTION")
public String getName_Institution() {
return Name_Institution;
}
public void setName_Institution(String name_Institution) {
Name_Institution = name_Institution;
}
private Type type_inInstitution;
@ManyToOne
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@JoinTable(name="TYPE_INSTITUTION",
joinColumns=@JoinColumn(name="INSTITUTION_ID"),
inverseJoinColumns=@JoinColumn(name="TYPE_ID"))
public Type getType_inInstitution() {
return type_inInstitution;
}
public void setType_inInstitution(Type type_inInstitution) {
this.type_inInstitution = type_inInstitution;
}
}
My second entity class:
@Entity
@Table(name="TYPE")
public class Type implements Serializable {
private static final long serialVersionUID = -4246217431412815552L;
private String type;
public Type(){}
public Type(String type) {
this.type = type;
}
private int Type_Id;
@Id
@GeneratedValue(strategy=IDENTITY)
@Column(name="ID")
public int getType_Id() {
return Type_Id;
}
public void setType_Id(int type_Id) {
Type_Id = type_Id;
}
private String Type_Name;
@Column(name="TYPE_NAME")
public String getType_Name() {
return Type_Name;
}
public void setType_Name(String type_Name) {
Type_Name = type_Name;
}
private int Version;
@Version
@Column(name="VERSION")
public int getVersion() {
return Version;
}
public void setVersion(int version) {
Version = version;
}
private Set<Institution> set_Institution_inType = new HashSet<Institution>();
@OneToMany
@JoinTable(name="TYPE_INSTITUTION", joinColumns=@JoinColumn(name="TYPE_ID"), inverseJoinColumns=@JoinColumn(name="INSTITUTION_ID"))
public Set<Institution> getSet_Institution_inType() {
return set_Institution_inType;
}
public void setSet_Institution_inType(Set<Institution> set_Institution_inType) {
this.set_Institution_inType = set_Institution_inType;
}
public void addType(Institution institution) {
institution.setType_inInstitution(this);
getSet_Institution_inType().add(institution);
}
}
The DAO Class:
@Repository("daoInsertDataInterface")
@Transactional
public class InsertDataService implements DaoInsertDataInterface{
private org.apache.commons.logging.Log log= LogFactory.getLog(InsertDataService.class);
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource(name="sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public Institution insertData(Institution institution) {
sessionFactory.getCurrentSession().saveOrUpdate(institution);
log.info(institution.getId());
return institution;
}
}
My metada config:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.connectionValues}</value></property>
<property name="username"><value>${jdbc.userName}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref ="sessionFactory"/>
</bean>
<context:property-placeholder location="connection.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="edu.demidov.dom, edu.demidov.dao" />
<context:annotation-config />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref ="dataSource"/>
<property name="packagesToScan" value="edu.demidov.dom"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
And the error:
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [app-context.xml] INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning INFO : org.springframework.context.support.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@c93274: startup date [Thu May 09 11:38:23 EDT 2013]; root of context hierarchy INFO : org.springframework.beans.factory.config.PropertyPlaceholderConfigurer - Loading properties file from class path resource [connection.properties] INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1b9c2f0: defining beans [dataSource,transactionManager,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,daoInsertDataInterface,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,sessionFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor];
root of factory hierarchy Hibernate: insert into TYPE (TYPE_NAME, VERSION) values (?, ?) WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: 1048, SQLState: 23000 ERROR: org.hibernate.util.JDBCExceptionReporter - Column 'TYPE_NAME' cannot be null Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not insert: [edu.demidov.dom.Type] at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2327) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2834) at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677) at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252) at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392) at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335) at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204) at org.hibernate.engine.Cascade.cascade(Cascade.java:161) at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673) at edu.demidov.dao.InsertDataService.insertData(InsertDataService.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy22.insertData(Unknown Source) at edu.demidov.dao.AppTEst.main(AppTEst.java:22) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'TYPE_NAME' cannot be null at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:525) at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) at com.mysql.jdbc.Util.getInstance(Util.java:386) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57) ... 44 more SS
Thank you, guys.
Why I should use JoinTable insted of Foreign Key?
You should not. You have the choice. If you prefer using a join table, use a join table. If you prefer using a join column (foreign key in the child table), use a join column. If you have an already existing schema that you can't change, choose the option that corresponds to the existing schema.
how entity work's and collaborate with each other
I'm not sure what you mean by that. If an entity School has a OneToMany association with an entity Teacher, when you get a school from the session, and ask for its teachers, Hibernate will load them from the database for you. If you add a teacher to the collection of teachers of a school, Hibernate will populate the join column or the join table for you. The goal is simply to manipulate objects as if theyr were simple objects stored in memory, and have Hibernate load and save them for you from/to the database.
Now regarding the exception and the title of your question, the exception message says it clearly:
insert into TYPE (TYPE_NAME, VERSION) values (?, ?) WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: 1048, SQLState: 23000 ERROR: org.hibernate.util.JDBCExceptionReporter - Column 'TYPE_NAME' cannot be null
You're trying to insert an antity of type Type (what a badly chosen name!) with a null name. And the database column doesn't acept null. So you get this exception. Either change the table definition if null is a valid Type name, or fix your code to make sure you don't try to insert a null name.
Also, respect the Java naming conventions. Your code is really hard to read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With