我試圖實現Hibernate映射到Oracle默認安裝提供的示例架構(Order Entry) orderentry架構有幾個表其中一個是Customer表,它具有很少的列作爲customTyped列,例如 自定義類型是使用以下語句創建的;實現自定義休眠類型
CREATE OR REPLACE TYPE "CUST_ADDRESS_TYP" AS OBJECT
(street_address VARCHAR2(40)
, postal_code VARCHAR2(10)
, city VARCHAR2(30)
, state_province VARCHAR2(10)
, country_id CHAR(2)
);
和客戶表與下面的語句
CREATE TABLE OE.CUSTOMERS
(
CUSTOMER_ID NUMBER (6) NOT NULL ,
CUST_FIRST_NAME VARCHAR2 (20 BYTE)
CONSTRAINT CUST_FNAME_NN NOT NULL ,
CUST_LAST_NAME VARCHAR2 (20 BYTE)
CONSTRAINT CUST_LNAME_NN NOT NULL ,
CUST_ADDRESS OE.CUST_ADDRESS_TYP ,
)
創建我才知道,我們需要從here實現UserType
接口,但是當我試圖找回它是給錯誤
org.hibernate.MappingException: property mapping has wrong number of columns: com.dto.oe.Customers.cust_addressData type: com.dto.oe.CustAddressType
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:497)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
at com.test.connection.HibernateUtil.getSession(HibernateUtil.java:82)
at com.test.connection.HibernateUtil.getCustomer(HibernateUtil.java:70)
at com.test.connection.HibernateUtil.main(HibernateUtil.java:18)
Wheras my Customtype
對象pojo類是Cust_addressData
和實現usert的類YPE接口是CustAddressType
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
public class CustAddressType implements UserType {
/**
* Returns the object from the 2 level cache
*/
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
/**
* Used to create Snapshots of the object
*/
public Object deepCopy(Object value) throws HibernateException {
final Cust_addressData recievedParam = (Cust_addressData) value;
final Cust_addressData addressData = new Cust_addressData(recievedParam);
return addressData;
}
/**
* method called when Hibernate puts the data in a second level cache. The
* data is stored in a serializable form
*/
public Serializable disassemble(final Object value)
throws HibernateException {
return (Serializable) value;
}
public boolean equals(final Object o1, final Object o2)
throws HibernateException {
boolean isEqual = false;
if (o1 == o2) {
isEqual = true;
}
if (null == o1 || null == o2) {
isEqual = false;
} else {
isEqual = o1.equals(o2);
}
return isEqual;
// for this to work correctly the equals()
// method must be implemented correctly by Cust_addressData class
}
public int hashCode(final Object arg0) throws HibernateException {
return arg0.hashCode();
}
public boolean isMutable() {
return true;
}
public Object nullSafeGet(final ResultSet resultSet, final String[] names,
SessionImplementor sessionImp, final Object owner)
throws HibernateException, SQLException {
// owner here is class from where the call to retrieve data was made.
// In this case the Test class
Cust_addressData addresssData = new Cust_addressData();
// Order of columns is given by sqlTypes() method
if (!resultSet.wasNull()) {
final String street_address = resultSet.getString(names[0]);
final String postal_code = resultSet.getString(names[1]);
final String city = resultSet.getString(names[2]);
final String state_province = resultSet.getString(names[3]);
final String country_id = resultSet.getString(names[4]);
addresssData.setCity(city);
addresssData.setCountry_id(country_id);
addresssData.setPostal_code(postal_code);
addresssData.setState_province(state_province);
addresssData.setStreet_address(street_address);
System.out.println("street_address "+street_address +" names "+names[0]);
} else {
System.err.println("resultSet is null in CustAddressType");
}
return addresssData;
}
public void nullSafeSet(final PreparedStatement statement, final Object value, final int index,
SessionImplementor arg3) throws HibernateException, SQLException {
if (null == value) {
statement.setNull(index, Types.VARCHAR);
statement.setNull(index + 1, Types.VARCHAR);
statement.setNull(index + 2, Types.VARCHAR);
statement.setNull(index + 3,Types.VARCHAR);
statement.setNull(index + 4,Types.VARCHAR);
} else {
Cust_addressData addressData = (Cust_addressData) value;
if (null != addressData.getStreet_address()) {
String street_address = new String(addressData.getStreet_address());
statement.setString(index , street_address);
} else {
statement.setNull(index , Types.VARCHAR);
}
if (null != addressData.getPostal_code()) {
String postal_Code = new String(addressData.getPostal_code());
statement.setString(index+1 , postal_Code);
} else {
statement.setNull(index +1, Types.VARCHAR);
}
if (null != addressData.getCity()) {
String city = new String(addressData.getCity());
statement.setString(index+2 , city);
} else {
statement.setNull(index +2, Types.VARCHAR);
}
if (null != addressData.getState_province()) {
String postal_Code = new String(addressData.getState_province());
statement.setString(index+3 , postal_Code);
} else {
statement.setNull(index +3, Types.VARCHAR);
}
if (null != addressData.getCountry_id()) {
String postal_Code = new String(addressData.getCountry_id());
statement.setString(index+4 , postal_Code);
} else {
statement.setNull(index +4, Types.VARCHAR);
}
}
}
public Object replace(final Object original, final Object target,
final Object owner) throws HibernateException {
return this.deepCopy(original);
}
@SuppressWarnings("rawtypes")
public Class returnedClass() {
return Cust_addressData.class;
}
public int[] sqlTypes() {
return new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR, Types.VARCHAR };
}
}
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@SuppressWarnings("serial")
@Entity
@Table(name="CUST_ADDRESS_TYP")
public class Cust_addressData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name = "street_address")
private String street_address;
@Column(name = "postal_code")
private String postal_code;
@Column(name = "city")
private String city;
@Column(name = "state_province")
private String state_province;
@Column(name = "country_id")
private String country_id;
public Cust_addressData() {
}
public Cust_addressData(Cust_addressData other) {
this.setCity(other.getCity());
this.setCountry_id(other.getCountry_id());
this.setPostal_code(other.getPostal_code());
this.setStreet_address(other.getStreet_address());
this.setState_province(other.getState_province());
}
public String getStreet_address() {
return street_address;
}
public void setStreet_address(String street_address) {
this.street_address = street_address;
}
public String getPostal_code() {
return postal_code;
}
public void setPostal_code(String postal_code) {
this.postal_code = postal_code;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState_province() {
return state_province;
}
public void setState_province(String state_province) {
this.state_province = state_province;
}
public String getCountry_id() {
return country_id;
}
public void setCountry_id(String country_id) {
this.country_id = country_id;
}
@Override
public boolean equals(Object obj) {
boolean isEqual = false;
if (obj instanceof Cust_addressData) {
Cust_addressData addressData = (Cust_addressData) obj;
isEqual = addressData.getCity().equals(this.getCity())
&& addressData.getState_province().equals(this.getState_province())
&& addressData.getCountry_id().equals(this.getCountry_id())
&& addressData.getPostal_code().equals(this.getPostal_code())
&& addressData.getStreet_address().equals(this.getStreet_address())
;
}
return isEqual;
}
@Override
public int hashCode() {
int hash = this.getCountry_id().hashCode();
hash = hash * 17 + this.getPostal_code().hashCode();
hash = hash * 31 + this.getStreet_address().hashCode();
hash = hash * 13 + this.getState_province().hashCode();
hash = hash * 14 + this.getCity().hashCode();
return hash;
}
@Override
public String toString() {
return "[ " + this.getClass() + " { city : " + city
+ ", street_address: " + street_address + ", postal_code: "
+ postal_code + ", state_province: " + state_province + ""
+ ",country_id :"+country_id+"}]";
}
}
全來源:
還有一個觀察是的SQLType方法是在CustAddressType類
public int[] sqlTypes() {
return new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR, Types.VARCHAR };
}
是正在返回的列數的一個,如果我讓它返回只有一列,我發現了列值作爲空。
不知道什麼是布萊恩錯了,我哪裏做錯了或任何線索將
可能:http://stackoverflow.com/questions/23942960/hibernate-compositeusertype-mapping-has-wrong-列數 – 2016-02-08 06:26:07
我已經實現了UserType接口而不是CompositeUserType ..此外我也嘗試過使用CompositeUserType,但問題依然存在。 –
你有沒有試過[這篇博文](http://dinukaroshan.blogspot.co。uk/2009/08/hibernate-and-oracle-user-defined-types.html)儘可能接近? –