Сопоставить одну сущность с разными столбцами одной таблицы, используя Hibernate - PullRequest
0 голосов
/ 03 июля 2019

У меня есть простое банковское приложение, в котором есть сущность Account and Transaction.Одна учетная запись сохраняет транзакции снятия и депозита (они могут быть между двумя учетными записями или учетной записью и банкоматом (в соответствующем поле он будет нулевым). Я использую аннотации @ManyToOne и @OneToMany и хочу сохранить идентификаторы таблицы транзакций обоих полей из поля fromAccount иtoAccount, но я получил исключение, которое вы можете увидеть ниже. Я понимаю, что это происходит из-за сопоставления с тем же полем (account_id), но как я могу это исправить, если мне нужно использовать поле id? Мой код examlpe:

public class Account {
@OneToMany(fetch = FetchType.LAZY,
        mappedBy = "fromAcc",
        cascade = CascadeType.ALL)
private List<Transaction> withdrawTransactions = new ArrayList<>();

@OneToMany(fetch = FetchType.LAZY,
        mappedBy = "toAcc",
        cascade = CascadeType.ALL)
private List<Transaction> depositTransactions = new ArrayList<>();

и

public class Transaction {
@ManyToOne
@JoinColumn(name = "account_id")
private Account fromAcc;
@ManyToOne
@JoinColumn(name = "account_id")
private Account toAcc;

Исключение, которое я получил:

 Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: BankAppSimple] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1012)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:938)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at bank.app.simple.util.JpaUtil.getEntMngFactoryInstance(JpaUtil.java:18)
at bank.app.simple.util.JpaUtil.createEntityManager(JpaUtil.java:30)
at bank.app.simple.daoimpl.ExchangeRateDaoImpl.isCurrencyExist(ExchangeRateDaoImpl.java:19)
at bank.app.simple.serviceimpl.ExchangeRateServiceImpl.addRate(ExchangeRateServiceImpl.java:19)
at bank.app.simple.Main.fillTables(Main.java:46)
at bank.app.simple.Main.main(Main.java:26)

и

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: bank.app.simple.entity.Transaction column: account_id (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634)
at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:343)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:461)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
... 9 more

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Я думаю, что вы забыли установить столбец соединения в вашей Transaction сущности. Просто замените FROM_ACC_COLUMN и TO_ACC_COLUMN соответствующими именами столбцов из таблицы транзакций.

public class Transaction {

    @ManyToOne
    @JoinColumn(name = "FROM_ACC_COLUMN", referencedColumnName = "account_id")
    private Account fromAcc;

    @ManyToOne
    @JoinColumn(name = "TO_ACC_COLUMN", referencedColumnName = "account_id")
    private Account toAcc;

}

И лично я бы не стал использовать CascadeType.ALL в этом случае, вместо этого попробуйте {CascadeType.PERSIST, CascadeType.MERGE}.

0 голосов
/ 03 июля 2019

Если кто-то заинтересовался, решение, которое работало для меня, состояло в том, чтобы переименовать поле отображения в сущности с аннотацией @ManyToOne и добавить префикс перед "account_id" + "referencedColumnName =" account_id "":

@ManyToOne
@JoinColumn(name = "from_account_id", referencedColumnName = "account_id") // add from_
private Account fromAcc;
@ManyToOne
@JoinColumn(name = "to_account_id", referencedColumnName = "account_id") // add to_
private Account toAcc;

Спасибо, @ t4dohx, за совет!

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