Сортированная коллекция в Hibernate - PullRequest
0 голосов
/ 15 января 2012

Мой класс домена выглядит следующим образом:

package org.hibernate.auction.model;

import java.util.SortedMap;
import java.util.TreeMap;

import org.hibernate.auction.util.ReverseStringComparator;

public class Item {

    private Long id;
    private String name;
    private SortedMap<String,String> images = new TreeMap<String,String>(new ReverseStringComparator());
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public SortedMap<String,String> getImages() {
        return images;
    }
    public void setImages(SortedMap<String,String> images) {
        this.images = images;
    }

    public void addImage(String imageName,String fileName){
        images.put(imageName, fileName);

    }

}

Соответствующий файл сопоставления Item.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 Jan 14, 2012 10:34:00 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="org.hibernate.auction.model.Item" table="ITEM">
        <id name="id" type="java.lang.Long">
            <column name="ITEM_ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <map name="images" table="ITEM_IMAGE" sort="org.hibernate.auction.util.ReverseStringComparator">
            <key column="ITEM_ID"/>
            <map-key type="java.lang.String" column="IMAGENAME"></map-key>
            <element type="java.lang.String" column="FILENAME" not-null="true"/>        
         </map>
    </class>
</hibernate-mapping>

Компаратор выглядит следующим образом:

package org.hibernate.auction.util;

import java.util.Comparator;

public class ReverseStringComparator implements Comparator<String> {

    public int compare(String strA, String strB){
        // Compare strB to strA, rather than strA to strB.
        return strB.compareTo(strA);
    }

}

Конфигурация hibernate.cfg.xml выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">mysql123</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jpwh_ch6_1_6</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.use_sql_comments">true</property>
  <property name="hibernate.format_sql">true</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <mapping resource="org/hibernate/auction/model/Item.hbm.xml"/>
 </session-factory>
</hibernate-configuration>

Тестируемое Java-приложение выглядит следующим образом:

package org.hibernate.auction.model;

import org.hibernate.Session;
import org.hibernate.Transaction;
import persistence.HibernateUtil;
    public class JpwhCh6_1_6Main {
        public static void main(String[] args) {
            Session session = HibernateUtil.getSessionFactory().openSession();
            Transaction tx = session.beginTransaction();
            Item item1 = new Item();
            item1.setName("Foo");
            item1.addImage("Image One", "fooimage1.jpg");
            item1.addImage("Image Two", "fooimage2.jpg");
            item1.addImage("Image Three", "fooimage3.jpg");
            System.out.println(item1.getImages());


            Item item2 = new Item();
            item2.setName("Bar");

            Item item3 = new Item();
            item3.setName("Baz");
            session.save(item1);
            session.save(item2);
            session.save(item3);
            tx.commit();

            session.close();
            HibernateUtil.shutdown();

        }

    }

HibernateUtil выглядит следующим образом:

package persistence;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
     private static SessionFactory sessionFactory;

      static {
        try {
           sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
           throw new ExceptionInInitializerError(ex);
        }
      }

      public static SessionFactory getSessionFactory() {
          // Alternatively, we could look up in JNDI here
          return sessionFactory;
      }

      public static void shutdown() {
          // Close caches and connection pools
          getSessionFactory().close();
      }

}

В базе данных она хранится так:

ITEM_ID FILENAME    IMAGENAME
1   fooimage1.jpg   Image One
1   fooimage3.jpg   Image Three
1   fooimage2.jpg   Image Two

Очевидно, я ожидал, что это будет в порядке Image Two, Image Three, Image One.Чего мне не хватаетЭто из книги «Сохранение Java с Hibernate».Я использую версию Hibernate 3.6.9.Я пробовал все 3 варианта сортировки: несортированный, натуральный, имя класса компаратора. Они не имеют никакого эффекта.

Ответы [ 2 ]

0 голосов
/ 31 января 2013

Проблема заключается в вашем классе Comparator. Предоставленный вами метод сравнения возвращает значение типа int на основе сравнения двух строк (1, если strA> strB, 0, если strA == strB, и -1, если strA

@Override
public int compare(String strA, String strB){
    if(strB.equals(strB) {
        return 0;
    } else {
        return -strB.compareTo(strA);
    }
}
0 голосов
/ 15 января 2012

Что вам не хватает, так это то, что Hibernate заменяет ваш TreeMap собственной реализацией Map для реализации каскадирования, отложенной загрузки и т. Д., И что Hiberbate не может знать, что карта должна быть отсортирована в соответствии с вашей компаратор.

Таким образом, вы должны указать Hibernate, что ваша карта должна быть отсортирована, и указать класс используемого компаратора. Смотри http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#d0e10663.

Обратите внимание, что, поскольку вы предоставляете установщик для этой карты и слепо заменяете текущую карту картой, переданной в качестве аргумента, любой может заменить карту другой, которая не сортируется таким же образом. Для этого свойства не должно быть публичного сеттера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...