A1ucard A1ucard - 1 month ago 17
Java Question

java:Hibernate One To Many Association

I had encounter some problem for hibernate framework.

Let say I have a person, and a person have multiple address. Below is my code,

/* Person entity*/
@Entity
@Table(name="person")
public class Person implements Serializable{

private static final long serialVersionUID = 7635130386543844954L;

@Id
@Column(name="person_id")
private Integer personId;

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

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

@OneToMany(fetch=FetchType.EAGER)
@JoinTable(name="address",
joinColumns{@JoinColumn(name="name")},inverseJoinColumns={@JoinColumn(name="address_id")})
List<Address> listAddress = new ArrayList<Address>();

public Integer getPersonId() {
return personId;
}

public void setPersonId(Integer personId) {
this.personId = personId;
}

public String getName() {
return name;
}

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

public String getIcNo() {
return icNo;
}

public void setIcNo(String icNo) {
this.icNo = icNo;
}

}

/* Address entity*/
@Entity
@Table(name="address")
public class Address implements Serializable{

private static final long serialVersionUID = 1371825219482824135L;

@Id
@Column(name="address_id")
private Integer addressId;

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

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

public Integer getAddressId() {
return addressId;
}

public void setAddressId(Integer addressId) {
this.addressId = addressId;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getName() {
return name;
}

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


/* DAO code*/
List<ProductDetails>list = hibernateTemplate.find("from Person where Name=?",new Object[]{name});


When I try to execute the program, I get the exception as following:

Exception in thread "main" org.springframework.dao.InvalidDataAccessResourceUsageException: could not initialize a collection: [com.inventory.inventory.vo.Person.listAddress#1]; nested exception is org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.inventory.inventory.vo.Person.listAddress#1]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:630)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:921)
at com.inventory.inventory.dao.impl.ProductsDAOImpl.getProductsByCode(ProductsDAOImpl.java:28)
at Main.main(Main.java:14)
Caused by: org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.inventory.inventory.vo.Person.listAddress#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2069)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:628)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1853)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:476)
at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:899)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:275)
at org.hibernate.loader.Loader.doList(Loader.java:2294)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)
at org.hibernate.loader.Loader.list(Loader.java:2167)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:448)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1258)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:930)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
... 4 more

<b>Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: character varying = integer</b>

Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 305
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1849)
at org.hibernate.loader.Loader.doQuery(Loader.java:718)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2062)
... 21 more


The only thing I make it different is, I use column "name" with Character datatype to join the table and inverse join is use address id which is integer datatype. Is anyway to map the view object with different datatype?

Answer

Try this

Modify Person class as

@OneToMany(cascade=mappedBy = "person", fetch = FetchType.EAGER)
private List<Address> listAddress = new ArrayList<Address>();

Modify Address class as

@JoinColumn(name = "person_id", referencedColumnName = "person_id")
@ManyToOne
private Person person;