简体   繁体   中英

Setting the value of a column according to the count() of the referred rows in another table to my table in SQL and hibernate mapping

I have the following tables in my database. I want the column booked_items in the testuser table to contain the number of rows associated with the user in the testbooking table. It is surely can be done inside the programme but it is dirty if it can be done in the hibernate mapping and the table DDL.

CREATE TABLE `testuser` (
  `id` bigint(20) NOT NULL,
  `username` varchar(30) DEFAULT NULL,
  `password` varchar(128) DEFAULT NULL,
  `booked_items` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `testbooking` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `item_id` bigint(20) NOT NULL,
  `start_date` date DEFAULT NULL,
  `end_date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKEC747367A12BE486` (`item_id`),
  KEY `FKEC7473671463A66C` (`user_id`),
  CONSTRAINT `FKEC7473671463A66C` FOREIGN KEY (`user_id`) REFERENCES `testuser`
(`id`),
  CONSTRAINT `FKEC747367A12BE486` FOREIGN KEY (`item_id`) REFERENCES `testitem`
(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

CREATE TABLE `testitem` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1;

The hibernate mapping for the testuser table is:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="my.hibernate.actors.User" discriminator-value="user"
        table="testuser" catalog="efeu">
        <id name="id" type="java.lang.Long">
            <column name="id" />
            <generator class="increment" />
        </id>
        <discriminator column="user_type" type="string" length="8" />
        <property name="username" type="java.lang.String" not-null="true"
            unique="true" unique-key="true">
            <column name="username" length="30" />
        </property>
        <property name="password" type="java.lang.String" not-null="true">
            <column name="password" length="128" />
        <subclass name="my.hibernate.actors.Subscriber"
            discriminator-value="subsc">
            <property name="bookedItems" type="java.lang.Integer" column="booked_items" />
            <set name="bookings" inverse="true" cascade="all-delete-orphan">
                <key column="user_id" />
                <one-to-many class="my.hibernate.operations.Booking" />
            </set>
        </subclass>
        <subclass name="my.hibernate.actors.Clerk"
            discriminator-value="clerk" />
    </class>
</hibernate-mapping>

The hibernate mapping for the testbooking table is:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="my.hibernate.operations.Booking" table="testBooking" catalog="efeu">
        <id name="id" type="java.lang.Long">
            <column name="id" />
            <generator class="native" />
        </id>

        <many-to-one name="userID" column="user_id" cascade="persist"
            not-null="true" class="my.hibernate.actors.Subscriber" />
        <many-to-one name="itemID" column="item_id"  cascade="persist"
            not-null="true" class="my.hibernate.items.Item" />

        <property name="startDate" type="java.sql.Date" not-null="true">
            <column name="start_date" length="10" />
        </property>

        <property name="endDate" type="java.sql.Date">
            <column name="end_date" length="10" />
        </property>
    </class>
</hibernate-mapping>

PS. I wanted to ask 2 separate questions for this issue. Once for Hibernate and once for SQL but I was afraid it would be considered as a duplicate. For Hibernate need to know for SQL I'm interested to know. And does it depend on the dialect of the SQL? I'm currently asking for mysql dialect.

You can use a property on the user class with a sql formula associated to it.

<property name="booked_items" type="long" formula="(SELECT COUNT(tb.id) FROM testbooking AS tb WHERE tb.user_id = id)"/>

Have a look at this answer: seems like duplicate

Calculated property with JPA / Hibernate

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