我正在尝试将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)
);
并使用以下语句
创建customer表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)
我的Customtype
对象pojo类是Cust_addressData
,实现usertype接口的类是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+"}]";
}
}
完整资料来源:
另一个观察结果是在CustAddressType类
中的sqlTypes方法public int[] sqlTypes() {
return new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR, Types.VARCHAR };
}
是返回列数的那个,如果我让它只返回一列我将列值变为null。
不确定究竟出了什么问题,任何建议,我做错了或任何线索将不胜感激
答案 0 :(得分:5)
在我的CustAddressType
类中使用STRUCT类解决了CustAddressType
类的源代码如下问题。
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Struct;
import java.sql.Types;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
public class CustAddressType implements UserType {
private static final int SQL_TYPE = Types.STRUCT;
private static final String OBJECT_TYPE = "CUST_ADDRESS_TYP";
/**
* 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 {
if (value == null) {
return null;
}
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
final Cust_addressData addresssData = new Cust_addressData();
final Struct struct = (Struct) resultSet.getObject(names[0]);
if (resultSet.wasNull()) {
return null;
}
addresssData.setCity((String)struct.getAttributes()[0]);
addresssData.setCountry_id((String)struct.getAttributes()[1]);
addresssData.setPostal_code((String)struct.getAttributes()[2]);
addresssData.setState_province((String)struct.getAttributes()[3]);
addresssData.setStreet_address((String)struct.getAttributes()[4]);
return addresssData;
}
public void nullSafeSet(final PreparedStatement statement, final Object value, final int index,
SessionImplementor arg3) throws HibernateException, SQLException {
if (value == null) {
statement.setNull(index, SQL_TYPE, OBJECT_TYPE);
}
else {
final Cust_addressData addresssData = (Cust_addressData) value;
final Object[] values = new Object[] { addresssData.getCity(),addresssData.getCountry_id(), addresssData.getPostal_code(),
addresssData.getState_province(),addresssData.getStreet_address() };
final Connection connection = statement.getConnection();
final STRUCT struct = new STRUCT(StructDescriptor.createDescriptor( OBJECT_TYPE,connection), connection, values);
statement.setObject(index, struct, SQL_TYPE);
}
}
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[] {SQL_TYPE};
}
}
感谢 @SteveChambers 指出它,
答案 1 :(得分:0)
我的朋友hibernate Annotations在哪里?你必须清楚地用名称包括你的表名来定义每个字段......
import java.io.Serializable;
@Entity
@Table(name = "CUST_ADDRESS_TYP")
public class Cust_addressData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name ="column_name")
private String street_address;
@Column(name ="column_name")
private String postal_code;
@Column(name ="column_name")
private String city;
@Column(name ="column_name")
private String state_province;
@Column(name ="column_name")
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+"}]";
}
尝试为每个变量顶部的每一列添加正确的名称,不要公开。祝你好运