Разделение одной ассоциации БД на несколько коллекций в Hibernate - PullRequest
2 голосов
/ 07 декабря 2009

Я пытаюсь смоделировать такую ​​ситуацию - есть денежный перевод (я имею в виду автомобиль, который перевозит деньги), в котором требуются суммы каждой валюты, а также фактическая сумма для каждой валюты. И мне кажется бессмысленным создавать два отдельных класса, один для требуемой суммы, а другой для фактической суммы. Поэтому реализация будет выглядеть так:

@Entity
public class CashTransferCurrencyAmount {
    // id, version and so on

    @Column(length = 3)
    private String currencyCode;

    @Basic
    private BigDecimal amount;

    @ManyToOne
    private CashTransfer cashTransfer;
}

@Entity
public class CashTransfer {
    // id, version and so on

    @OneToMany(mappedBy="cashTransfer")
    private Set<CashTransferCurrencyAmount> requiredCurrencyAmountSet = new HashSet<CashTransferAmountCurrency>();

    @OneToMany(mappedBy="cashTransfer")
    private Set<CashTransferCurrencyAmount> actualCurrencyAmountSet = new HashSet<CashTransferAmountCurrency>();
}

Но как экземпляру CashTransferCurrencyAmount узнать, к какой коллекции он принадлежит? У меня есть две идеи:

1 - добавить поле дискриминатора в CashTransferCurrencyAmount:

public enum RequestType {
    ACTUAL,
    REQUIRED
}

@Basic
@Enumerated(EnumType.STRING)
private RequestType requestType;

и добавьте @WHERE аннотаций к коллекциям в CashTransfer. Это предпочтительнее для меня.

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

Есть ли другие способы достичь этого? Я этот подход правильный?
И , пожалуйста, , не говорите мне, чтобы я поместил как запрошенные, так и фактические суммы в одну организацию Реальный случай более сложный, каждый CashTransferCurrencyAmount имеет свои собственные коллекции, поэтому его нельзя решить таким образом.

EDIT
Что касается запросов на полную историю - раньше в CashTransferCurrencyAmount было два значения - обязательное (я думаю, что это «запрошенное») и фактическое, но теперь у каждой суммы есть своя коллекция - как эта сумма делится на деноминации. Поэтому мне нужна коллекция сумм, каждая из которых имеет коллекцию конфессий. Тип CurrencyAmount и CurencyDenomination, кажется, одинаков для запрошенных и для фактических.

1 Ответ

1 голос
/ 07 декабря 2009

Поскольку вы хотите, чтобы экземпляр CashTransferCurrencyAmount знал, к какой коллекции он принадлежит, я предполагаю, что вы хотите иметь некоторую логику, основанную на этом. Я бы смоделировал вашу ситуацию, используя наследование.

Вы говорите: "Мне кажется, бессмысленно создавать два отдельных класса", но я бы попытался убедить вас в этом. Вы можете использовать тип наследования «Одна таблица», чтобы не вводить дополнительные таблицы в вашу БД, чего вы и пытаетесь достичь.

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


@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "request_type", discriminatorType = DiscriminatorType.STRING)
public abstract class CashTransferCurrencyAmount {
    // id, version and so on

    @Column(length = 3)
    private String currencyCode;

    @Basic
    private BigDecimal amount;

    @ManyToOne
    private CashTransfer cashTransfer;
}

@Entity
@DiscriminatorValue("REQUIRED")
public class CashTransferCurrencyAmountRequired extends CashTransferCurrencyAmount {
    // required anount specific stuff here
}

@Entity
@DiscriminatorValue("ACTUAL")
public class CashTransferCurrencyAmountActual extends CashTransferCurrencyAmount {
    // actual anount specific stuff here
}

@Entity
public class CashTransfer {
    // id, version and so on

    @OneToMany(mappedBy="cashTransfer")
    private Set requiredCurrencyAmountSet = new HashSet();

//Stackoverflow deleting my generic sets! But it's exactly the same as in your code...

    @OneToMany(mappedBy="cashTransfer")
    private Set actualCurrencyAmountSet = new HashSet();
}
...