Hibernate工具:外键必须与引用的主键具有相同的列数

时间:2016-04-28 08:35:56

标签: oracle hibernate hibernate-mapping

我正在尝试实现Hibernate工具(逆向工程)。这是工具生成的.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">
   <!-- Generated Apr 28, 2016 1:37:34 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.telemune.bean.CrbtSubscriberMaster" table="CRBTSUBSCRIBERMASTER">
    <id name="corpId" type="int">
        <column name="CORPID" />
        <generator class="assigned" />
    </id>
    <property name="msisdn" type="java.lang.String">
        <column name="MSISDN" />
    </property>
    <property name="status" type="java.lang.String">
        <column name="STATUS" />
    </property>
    <property name="dateRegistered" type="java.util.Date">
        <column name="DATEREGISTERED" />
    </property>
    <property name="planIndicator" type="short">
        <column name="PLANINDICATOR" />
    </property>
    <property name="rbtCode" type="long">
        <column name="RBTCODE" />
    </property>
    <property name="password" type="java.lang.String">
        <column name="PASSWORD" />
    </property>
    <property name="tpin" type="java.lang.String">
        <column name="TPIN" />
    </property>
    <property name="freeEventsUsed" type="byte">
        <column name="FREEEVENTSUSED" />
    </property>
    <property name="blackListed" type="boolean">
        <column name="BLACKLISTED" />
    </property>
    <property name="language" type="boolean">
        <column name="LANGUAGE" />
    </property>
    <primitive-array name="defaultGroupSetting" table="CRBTSUBSCRIBERMASTER">
        <key>
            <column name="CORPID" />
        </key>
        <index></index>
        <element type="byte">
            <column name="DEFAULTGROUPSETTING" />
        </element>
    </primitive-array>
    <primitive-array name="defaultSingleSetting" table="CRBTSUBSCRIBERMASTER">
        <key>
            <column name="CORPID" />
        </key>
        <index></index>
        <element type="byte">
            <column name="DEFAULTSINGLESETTING" />
        </element>
    </primitive-array>
    <property name="dateSettingValidity" type="boolean">
        <column name="DATESETTINGVALIDITY" />
    </property>
    <property name="imsi" type="java.lang.String">
        <column name="IMSI" />
    </property>
    <property name="lastCharged" type="java.util.Date">
        <column name="LASTCHARGED" />
    </property>
    <property name="isMonthlyChargeable" type="java.lang.String">
        <column name="ISMONTHLYCHARGEABLE" />
    </property>
    <property name="subType" type="java.lang.String">
        <column name="SUBTYPE" />
    </property>
    <property name="renewMode" type="byte">
        <column name="RENEWMODE" />
    </property>
    <property name="expiryDate" type="java.util.Date">
        <column name="EXPIRYDATE" />
    </property>
    <property name="activeFeatures" type="java.lang.Boolean">
        <column name="ACTIVEFEATURES" />
    </property>
    <property name="inUseRbt" type="java.lang.Integer">
        <column name="INUSERBT" />
    </property>
    <property name="updateTime" type="java.util.Date">
        <column name="UPDATETIME" />
    </property>
    <property name="corpExpiry" type="java.util.Date">
        <column name="CORPEXPIRY" />
    </property>
</class>

这是我正在尝试应用查询(HQL)的代码:

public void getDetails() {

    try {

        Session session = sessionFactory.openSession();

        Transaction transaction = session.beginTransaction();

        String hql = "select c.msisdn, c.password FROM CrbtSubscriberMaster c where rownum<20";
        Query query = session.createQuery(hql);
        List<Object[]> itr = query.list();
        // System.out.println("[" + itr+ "]");
        session.getTransaction().commit();
        for (Object[] object : itr) {
            // CrbtSubMasterDemo pojo = (CrbtSubMasterDemo) iterator.next();
            System.out.println("["
                    + String.format("mobile:%s, password:%s", object[0],
                            object[1]) + "]");

        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

这就是Excetion Stack:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" org.hibernate.MappingException: Foreign key (FK3CFB77CBCAD1A7D6:CRBTSUBSCRIBERMASTER [CORPID])) must have same number of columns as the referenced primary key (CRBTSUBSCRIBERMASTER [CORPID,idx])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:112)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:95)
at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1805)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1726)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1393)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1826)
at com.telemune.demoHibernate.QueryTester.<init>(QueryTester.java:14)
at com.telemune.demoHibernate.QueryTester.main(QueryTester.java:18)

我是Hibernate的新手请帮助我理解并解决问题。提前致谢。

更新:CRBT_SUBSCRIBER_MASTER的DB描述

Name                       Null?    Type
----------------------------------------- ---------
MSISDN                   NOT NULL VARCHAR2(15)
STATUS                   NOT NULL VARCHAR2(3)
DATE_REGISTERED           NOT NULL DATE
PLAN_INDICATOR           NOT NULL NUMBER(3)
RBT_CODE                 NOT NULL NUMBER(10)
PASSWORD                 NOT NULL VARCHAR2(15)
TPIN                      NOT NULL VARCHAR2(4)
FREE_EVENTS_USED          NOT NULL NUMBER(2)
BLACK_LISTED              NOT NULL NUMBER(1)
LANGUAGE                  NOT NULL NUMBER(1)
DEFAULT_GROUP_SETTING     NOT NULL RAW(30)
DEFAULT_SINGLE_SETTING    NOT NULL RAW(30)
DATE_SETTING_VALIDITY     NOT NULL NUMBER(1)
IMSI                      NOT NULL VARCHAR2(20)
LAST_CHARGED                       DATE
IS_MONTHLY_CHARGEABLE              VARCHAR2(1)
CORP_ID                   NOT NULL NUMBER(5)

还有更多的colums。 根据我的知识,MSISDN是主键,但该工具似乎将Corp Id作为主键。

更新2:工具本身创建的Pojo类

@Entity
@Table(name = "CRBT_SUBSCRIBER_MASTER", schema = "SDP")
public class CrbtSubscriberMaster implements java.io.Serializable {

private String msisdn;
private String status;
private Date dateRegistered;
private short planIndicator;
private long rbtCode;
private String password;
private String tpin;
private byte freeEventsUsed;
private boolean blackListed;
private boolean language;
private byte[] defaultGroupSetting;
private byte[] defaultSingleSetting;
private boolean dateSettingValidity;
private String imsi;
private Date lastCharged;
private String isMonthlyChargeable;
private int corpId;
private String subType;
private byte renewMode;
private Date expiryDate;
private Boolean activeFeatures;
private Integer inUseRbt;
private Date updateTime;
private Date corpExpiry;

public CrbtSubscriberMaster() {
}

public CrbtSubscriberMaster(String msisdn, String status,
        Date dateRegistered, short planIndicator, long rbtCode,
        String password, String tpin, byte freeEventsUsed,
        boolean blackListed, boolean language, byte[] defaultGroupSetting,
        byte[] defaultSingleSetting, boolean dateSettingValidity,
        String imsi, int corpId, byte renewMode, Date updateTime) {
    this.msisdn = msisdn;
    this.status = status;
    this.dateRegistered = dateRegistered;
    this.planIndicator = planIndicator;
    this.rbtCode = rbtCode;
    this.password = password;
    this.tpin = tpin;
    this.freeEventsUsed = freeEventsUsed;
    this.blackListed = blackListed;
    this.language = language;
    this.defaultGroupSetting = defaultGroupSetting;
    this.defaultSingleSetting = defaultSingleSetting;
    this.dateSettingValidity = dateSettingValidity;
    this.imsi = imsi;
    this.corpId = corpId;
    this.renewMode = renewMode;
    this.updateTime = updateTime;
}

public CrbtSubscriberMaster(String msisdn, String status,
        Date dateRegistered, short planIndicator, long rbtCode,
        String password, String tpin, byte freeEventsUsed,
        boolean blackListed, boolean language, byte[] defaultGroupSetting,
        byte[] defaultSingleSetting, boolean dateSettingValidity,
        String imsi, Date lastCharged, String isMonthlyChargeable,
        int corpId, String subType, byte renewMode, Date expiryDate,
        Boolean activeFeatures, Integer inUseRbt, Date updateTime,
        Date corpExpiry) {
    this.msisdn = msisdn;
    this.status = status;
    this.dateRegistered = dateRegistered;
    this.planIndicator = planIndicator;
    this.rbtCode = rbtCode;
    this.password = password;
    this.tpin = tpin;
    this.freeEventsUsed = freeEventsUsed;
    this.blackListed = blackListed;
    this.language = language;
    this.defaultGroupSetting = defaultGroupSetting;
    this.defaultSingleSetting = defaultSingleSetting;
    this.dateSettingValidity = dateSettingValidity;
    this.imsi = imsi;
    this.lastCharged = lastCharged;
    this.isMonthlyChargeable = isMonthlyChargeable;
    this.corpId = corpId;
    this.subType = subType;
    this.renewMode = renewMode;
    this.expiryDate = expiryDate;
    this.activeFeatures = activeFeatures;
    this.inUseRbt = inUseRbt;
    this.updateTime = updateTime;
    this.corpExpiry = corpExpiry;
}

@Id
@Column(name = "MSISDN", unique = true, nullable = false, length = 15)
public String getMsisdn() {
    return this.msisdn;
}

public void setMsisdn(String msisdn) {
    this.msisdn = msisdn;
}

@Column(name = "STATUS", nullable = false, length = 3)
public String getStatus() {
    return this.status;
}

public void setStatus(String status) {
    this.status = status;
}

@Temporal(TemporalType.DATE)
@Column(name = "DATE_REGISTERED", nullable = false, length = 7)
public Date getDateRegistered() {
    return this.dateRegistered;
}

public void setDateRegistered(Date dateRegistered) {
    this.dateRegistered = dateRegistered;
}

@Column(name = "PLAN_INDICATOR", nullable = false, precision = 3, scale = 0)
public short getPlanIndicator() {
    return this.planIndicator;
}

public void setPlanIndicator(short planIndicator) {
    this.planIndicator = planIndicator;
}

@Column(name = "RBT_CODE", nullable = false, precision = 10, scale = 0)
public long getRbtCode() {
    return this.rbtCode;
}

public void setRbtCode(long rbtCode) {
    this.rbtCode = rbtCode;
}

@Column(name = "PASSWORD", nullable = false, length = 15)
public String getPassword() {
    return this.password;
}

public void setPassword(String password) {
    this.password = password;
}

@Column(name = "TPIN", nullable = false, length = 4)
public String getTpin() {
    return this.tpin;
}

public void setTpin(String tpin) {
    this.tpin = tpin;
}

@Column(name = "FREE_EVENTS_USED", nullable = false, precision = 2, scale = 0)
public byte getFreeEventsUsed() {
    return this.freeEventsUsed;
}

public void setFreeEventsUsed(byte freeEventsUsed) {
    this.freeEventsUsed = freeEventsUsed;
}

@Column(name = "BLACK_LISTED", nullable = false, precision = 1, scale = 0)
public boolean isBlackListed() {
    return this.blackListed;
}

public void setBlackListed(boolean blackListed) {
    this.blackListed = blackListed;
}

@Column(name = "LANGUAGE", nullable = false, precision = 1, scale = 0)
public boolean isLanguage() {
    return this.language;
}

public void setLanguage(boolean language) {
    this.language = language;
}

@Column(name = "DEFAULT_GROUP_SETTING", nullable = false)
public byte[] getDefaultGroupSetting() {
    return this.defaultGroupSetting;
}

public void setDefaultGroupSetting(byte[] defaultGroupSetting) {
    this.defaultGroupSetting = defaultGroupSetting;
}

@Column(name = "DEFAULT_SINGLE_SETTING", nullable = false)
public byte[] getDefaultSingleSetting() {
    return this.defaultSingleSetting;
}

public void setDefaultSingleSetting(byte[] defaultSingleSetting) {
    this.defaultSingleSetting = defaultSingleSetting;
}

@Column(name = "DATE_SETTING_VALIDITY", nullable = false, precision = 1, scale = 0)
public boolean isDateSettingValidity() {
    return this.dateSettingValidity;
}

public void setDateSettingValidity(boolean dateSettingValidity) {
    this.dateSettingValidity = dateSettingValidity;
}

@Column(name = "IMSI", nullable = false, length = 20)
public String getImsi() {
    return this.imsi;
}

public void setImsi(String imsi) {
    this.imsi = imsi;
}

@Temporal(TemporalType.DATE)
@Column(name = "LAST_CHARGED", length = 7)
public Date getLastCharged() {
    return this.lastCharged;
}

public void setLastCharged(Date lastCharged) {
    this.lastCharged = lastCharged;
}

@Column(name = "IS_MONTHLY_CHARGEABLE", length = 1)
public String getIsMonthlyChargeable() {
    return this.isMonthlyChargeable;
}

public void setIsMonthlyChargeable(String isMonthlyChargeable) {
    this.isMonthlyChargeable = isMonthlyChargeable;
}

@Column(name = "CORP_ID", nullable = false, precision = 5, scale = 0)
public int getCorpId() {
    return this.corpId;
}

public void setCorpId(int corpId) {
    this.corpId = corpId;
}

@Column(name = "SUB_TYPE", length = 3)
public String getSubType() {
    return this.subType;
}

public void setSubType(String subType) {
    this.subType = subType;
}

@Column(name = "RENEW_MODE", nullable = false, precision = 2, scale = 0)
public byte getRenewMode() {
    return this.renewMode;
}

public void setRenewMode(byte renewMode) {
    this.renewMode = renewMode;
}

@Temporal(TemporalType.DATE)
@Column(name = "EXPIRY_DATE", length = 7)
public Date getExpiryDate() {
    return this.expiryDate;
}

public void setExpiryDate(Date expiryDate) {
    this.expiryDate = expiryDate;
}

@Column(name = "ACTIVE_FEATURES", precision = 1, scale = 0)
public Boolean getActiveFeatures() {
    return this.activeFeatures;
}

public void setActiveFeatures(Boolean activeFeatures) {
    this.activeFeatures = activeFeatures;
}

@Column(name = "IN_USE_RBT", precision = 8, scale = 0)
public Integer getInUseRbt() {
    return this.inUseRbt;
}

public void setInUseRbt(Integer inUseRbt) {
    this.inUseRbt = inUseRbt;
}

@Temporal(TemporalType.DATE)
@Column(name = "UPDATE_TIME", nullable = false, length = 7)
public Date getUpdateTime() {
    return this.updateTime;
}

public void setUpdateTime(Date updateTime) {
    this.updateTime = updateTime;
}

@Temporal(TemporalType.DATE)
@Column(name = "CORP_EXPIRY", length = 7)
public Date getCorpExpiry() {
    return this.corpExpiry;
}

public void setCorpExpiry(Date corpExpiry) {
    this.corpExpiry = corpExpiry;
}

}

2 个答案:

答案 0 :(得分:0)

该工具很可能有错误或缺少功能。它没有生成正确的数组索引列。

<index></index>

应该是这样的:

<index column="idx"></index>

索引是存储数组的表的主要kay的一部分。需要在数组中存储顺序。

答案 1 :(得分:0)

好吧,伙计们。这是我使用Eclipse Luna帮助下载的Hibernate工具中的一个错误。而Bug的错误名称是表名映射。即。

<class name="com.telemune.bean.CrbtSubscriberMaster" table="CRBTSUBSCRIBERMASTER">

其中表的真实名称是CRBT_SUBSCRIBER_MASTER。即映射应为:

<class name="com.telemune.bean.CrbtSubscriberMaster" table="CRBT_SUBSCRIBER_MASTER">

我刚尝试过,它解决了我的问题。如果有人有解释为什么会这样?请解释。 更新: 我在这里注意到的另一个重要事项是选择图像中显示的选项 使用Java 5语法 可能会有所帮助。

enter image description here