Будьте в спящем режиме - Как сохранить новый объект в Наборе, не загружая весь Набор

Проверьте, ли векторное произведение из (b-a) и (c-a) 0, как говорит Darius Bacon, говорит Вам, если точки a, b и c выровненные.

, Но, поскольку Вы хотите знать, ли c между a и b, также необходимо проверить, что скалярное произведение из (b-a) и (c-a) положительно и меньше , чем квадрат расстояния между a и b.

В неоптимизированном псевдокоде:

def isBetween(a, b, c):
    crossproduct = (c.y - a.y) * (b.x - a.x) - (c.x - a.x) * (b.y - a.y)

    # compare versus epsilon for floating point values, or != 0 if using integers
    if abs(crossproduct) > epsilon:
        return False

    dotproduct = (c.x - a.x) * (b.x - a.x) + (c.y - a.y)*(b.y - a.y)
    if dotproduct < 0:
        return False

    squaredlengthba = (b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y)
    if dotproduct > squaredlengthba:
        return False

    return True
20
задан harriyott 15 March 2013 в 15:53
поделиться

3 ответа

Когда у вас есть коллекция на основе списка или набора и вы добавляете новый объект в свою коллекцию, Hibernate всегда будет попадать в базу данных, потому что он сравнивает один за другим объекты с использованием реализации равенства перед сохранением или обновление - при использовании Set - или путем сравнения столбца индекса при использовании List. Такое поведение необходимо из-за семантики Set и List. Из-за этого производительность вашего приложения может значительно снизиться, если у вас есть несколько записей.

Некоторые способы решения этой проблемы

Шаблон преобразования с использованием инкапсулированной коллекции Bag плюс желаемый набор или список предоставляется как свойство

@Entity
public class One {

    private Collection<Many> manyCollection = new ArrayList<Many>();

    @Transient
    public Set<Many> getManyCollectionAsSet() { return new HashSet<Many>(manyCollection); }
    public void setManyCollectionAsSet(Set<Many> manySet) { manyCollection = new ArrayList<Many>(manySet); }

    /**
      * Keep in mind that, unlike Hibernate, JPA specification does not allow private visibility. You should use public or protected instead
      */
    @OneToMany(cascade=ALL)
    private Collection<Many> getManyCollection() { return manyCollection; }
    private void setManyCollection(Collection<Many> manyCollection) { this.manyCollection = manyCollection; }

}

Использовать ManyToOne вместо OneToMany

@Entity
public class One {

    /**
      * Neither cascade nor reference
      */

}

@Entity
public class Many {

    private One one;

    @ManyToOne(cascade=ALL)
    public One getOne() { return one; }
    public void setOne(One one) { this.one = one }

}

Кэширование - когда применяется, в зависимости от ваших требований, ваша конфигурация может увеличить или уменьшить производительность вашего приложения. См. здесь

4 ° Ограничение SQL - если вам нужна коллекция, которая ведет себя как Set, вы можете использовать ограничение SQL, которое можно применить к столбцу или набору столбцов ]. См. здесь

11
ответ дан 30 November 2019 в 01:05
поделиться

Обычно я делаю это, определяя коллекцию как «инверсную».

Это примерно означает: первичное определение ассоциации 1-N делается на конце «N». Если вы хотите добавить что-то в коллекцию, вы изменяете связанный объект подробных данных.

Небольшой пример XML:

<class name="common.hibernate.Person" table="person">
    <id name="id" type="long" column="PERSON_ID">
        <generator class="assigned"/>
    </id>
    <property name="name"/>
    <bag name="addresses" inverse="true">
        <key column="PERSON_ID"/>
        <one-to-many class="common.hibernate.Address"/>
    </bag>
 </class>

 <class name="common.hibernate.Address" table="ADDRESS">
    <id name="id" column="ADDRESS_ID"/>
    <property name="street"/>
    <many-to-one name="person" column="PERSON_ID"/>
   </class>

, тогда обновление выполняется исключительно в Address:

Address a = ...;
a.setPerson(me);
a.setStreet("abc");
Session s = ...;
s.save(a);

Done. Вы даже коллекцию не трогали. Считайте его доступным только для чтения, что может быть очень практичным для запросов с HQL, а также для его повторения и отображения.

9
ответ дан 30 November 2019 в 01:05
поделиться

Если я хорошо понимаю вашу потребность:

  • у вас есть коллекция неизменяемых объектов только для добавления в памяти
  • как добавить элемент в эту коллекцию без инициализации всей коллекции (в текущем сеансе)?

Рассматривали ли вы сохранение вашей коллекции отключенной ?

  • Загружать ее один раз при запуске приложения
  • ] Добавление элемента означало бы две операции, выполняемые одной службой только в одном месте:
    • сохранить элемент (быстрая операция с базой данных, каскадирование с родительским элементом не выполняется)
    • добавить элемент в существующую отключенную коллекцию (без операций с базой данных)
2
ответ дан 30 November 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: