简体   繁体   中英

Mapping CHAR(0) in MySQL to boolean in Hibernate

I have a table named refund_rule in mysql (version 5.5) . Here is it's definition:

CREATE TABLE `refund_rule` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `PERCENTAGE` char(0) DEFAULT NULL COMMENT 'BOOLEAN shortcut.NULL<=>false,EMPTY<=>true',
  `DEDUCTION_AMOUNT` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`ID`)
);

The corresponding class in Hibernate (version 3.2) is named RefundRule . The HBM file looks like this:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="hibernatesample.dao.RefundRule" table="refund_rule" catalog="back_end_proc">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="percentage" type="string">
            <column name="PERCENTAGE" length="0">
                <comment>BOOLEAN shortcut.NULL&lt;=&gt;false,EMPTY&lt;=&gt;true</comment>
            </column>
        </property>
        <property name="deductionAmount" type="java.lang.Integer">
            <column name="DEDUCTION_AMOUNT" />
        </property>
    </class>
</hibernate-mapping>

The class generated by the wizard in NetBeans (version 7.0) was this:

public class RefundRule  implements java.io.Serializable {

     private Integer id;
     private String percentage;
     private Integer deductionAmount;

    public CancellationRule() {
    }

    public CancellationRule(String percentage, Integer deductionAmount) {
       this.percentage = percentage;
       this.deductionAmount = deductionAmount;
    }

    public Integer getId() {
        return this.id;
    }

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

    public String getPercentage() {
        return this.percentage;
    }

    public void setPercentage(String percentage) {
        this.percentage = percentage;
    }

    public Integer getDeductionAmount() {
        return this.deductionAmount;
    }

    public void setDeductionAmount(Integer deductionAmount) {
        this.deductionAmount = deductionAmount;
    }

}

I added 2 more methods in it setPercentage(boolean) & isPercentage() , and changed the method setPercentage(String) , so that i can use that String object as boolean in my Java (version 1.6) program.

public class RefundRule  implements java.io.Serializable {

    .
    .
    .

    public String getPercentage() {
        return this.percentage;
    }

    public void setPercentage(String percentage) {
        this.percentage = percentage==null?null:"";
    }

    .
    .
    .

    public void setPercentage(boolean percentage){
        setPercentage(percentage?"":null);
    }

    public boolean isPercentage(){
        return percentage!=null;
    }

}

My Question is:

Is there any way that I can keep only two methods: setPercentage(boolean) and isPercentage() , and map the boolean percentage variable to PERCENTAGE CHAR(0) variable in mysql.

===================================================================

added on 2013-11-23 添加于2013-11-23

Following the answer by @GreyBeardedGeek , I made following changes in code:

(Changes in brief)

  1. Added Class CharToBoolUserType
  2. Changed the type -attribute of hbm-element: percentage in RefundRule.hbm.xml

(Code related to above mentioned changes)

  1. The class CharToBoolUserType:

     import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import org.hibernate.HibernateException; import org.hibernate.usertype.UserType; public class CharToBoolUserType implements UserType { private static final int[] SQL_TYPES = {Types.CHAR}; @Override public Object assemble(Serializable serializable, Object object) throws HibernateException { return serializable; } @Override public Object deepCopy(Object object) throws HibernateException { return object; } @Override public Serializable disassemble(Object value) throws HibernateException { return (Serializable) value; } @Override public boolean equals(Object x, Object y) throws HibernateException { if (x == y) { return true; } else if (x == null || y == null) { return false; } else { return x.equals(y); } } @Override public boolean isMutable() { return false; } @Override public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException { return resultSet.getObject(names[0]) != null; } @Override public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException { preparedStatement.setObject(index, ((Boolean) value).booleanValue() ? "" : null); } @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } @Override public Class returnedClass() { return boolean.class; } @Override public int[] sqlTypes() { return SQL_TYPES; } @Override public int hashCode(Object object) throws HibernateException { if (object == null) { return 0; } // is `object` a String ? Or boolean? return 1; } } 
  2. The file RefundRule.hbm.xml:

     <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hibernatesample.dao.RefundRule" table="refund_rule" catalog="back_end_proc"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="identity" /> </id> <property name="percentage" type="hibernatesample.dao.CharToBoolUserType"> <column name="PERCENTAGE" length="0"> <comment>BOOLEAN shortcut.NULL&lt;=&gt;false,EMPTY&lt;=&gt;true</comment> </column> </property> <property name="deductionAmount" type="java.lang.Integer"> <column name="DEDUCTION_AMOUNT" /> </property> </class> </hibernate-mapping> 

Since I want the code of the class CharToBoolUserType to be complete in all sense, I have following questions:
1. What is the class of object in hashCode(Object object) , Boolean or String ? Who calls this method?
2. What the method public Object replace(Object original, Object target, Object owner) supposed to do? replace original with target and set/put it in owner . In this case: is original of String type, target of Boolean type, and owner of RefundRule type ?

Any suggestion(s) to improve this code is welcome.

=================================================

Just for reference, the class RefundRule is like this now:

public class RefundRule  implements java.io.Serializable {

     private Integer id;
     private boolean percentage;
     private Integer deductionAmount;

    public RefundRule() {
    }


    public RefundRule(boolean percentage, Integer deductionAmount) {
        this.percentage = percentage;
        this.deductionAmount = deductionAmount;
    }

    public Integer getId() {
        return this.id;
    }

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

    public Integer getDeductionAmount() {
        return this.deductionAmount;
    }

    public void setDeductionAmount(Integer deductionAmount) {
        this.deductionAmount = deductionAmount;
    }

    public void setPercentage(boolean percentage){
        this.percentage=percentage;
    }

    public boolean isPercentage(){
        return percentage;
    }

}

I believe that you are looking for Hibernate's UserType, which allows you to provide a custom type mapping.

See, for example, http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/types.html#types-custom

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM