Java @AssociationOverride в одной сущности портит ее в другой сущности - PullRequest
2 голосов
/ 06 августа 2020

У меня есть следующие объекты:

Предложение:

@Entity
public class Offer implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Embedded
    @AssociationOverride(name = "fees",
            joinTable = @JoinTable(
                    name = "offer_fees",
                    inverseJoinColumns = @JoinColumn(name = "fee_id", referencedColumnName = "id"),
                    joinColumns = @JoinColumn(name = "offer_id", referencedColumnName = "id")
            )
    )
    private Quote quote;

Цитата:

@Embeddable
public class Quote implements Serializable {

    @Column(precision = 13, scale = 3)
    private BigDecimal price;
    @OneToMany
    private List<Fee> fees = new ArrayList<>();

Плата:

@Entity
public class Fee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotNull
    @Column(precision = 8, scale = 4)
    private BigDecimal rate;

Каждый класс имеет геттеры и сеттеры по умолчанию. На данный момент все работает нормально. Но затем мне нужно добавить еще один объект:

@Entity
public class Purchase implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne
    private Offer offer;
    @Embedded
    @AssociationOverride(name = "fees",
        joinTable = @JoinTable(
                name = "purchase_fees",
                inverseJoinColumns = @JoinColumn(name = "fee_id", referencedColumnName = "id"),
                joinColumns = @JoinColumn(name = "purchase_id", referencedColumnName = "id")
        )
    )
    private Quote quote;

На этом этапе мои запросы перестают работать. Например, этот запрос:

public List<Purchase> getPurchases(BigDecimal price) {
    TypedQuery<Purchase> q = em.createQuery(
            "SELECT p FROM Purchase p"
            + " WHERE p.offer.quote.price = :price", Purchase.class);
    q.setParameter("price", price);

    return q.getResultList();
}

Возвращает эту ошибку:

org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist Posição: 8 Error Code: 0 Call: SELECT ID, PRICE FROM OFFER WHERE (ID = ?) bind => [1 parameter bound] Query: ReadObjectQuery(referenceClass=Offer sql="SELECT ID, PRICE FROM OFFER WHERE (ID = ?)")

Я установил drop-and-create в persistence.xml, чтобы узнать, смогу ли я найти, что не так:

        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>

И он генерирует таблицу Offer без идентификатора, и offer_fees тоже не ссылается на Offer, а на Purchase:

ALTER TABLE PURCHASE DROP CONSTRAINT FK_PURCHASE_OFFER_ID
ALTER TABLE offer_fees DROP CONSTRAINT FK_offer_fees_offer_id
ALTER TABLE offer_fees DROP CONSTRAINT FK_offer_fees_fee_id
ALTER TABLE purchase_fees DROP CONSTRAINT FK_purchase_fees_fee_id
SELECT 1
ALTER TABLE purchase_fees DROP CONSTRAINT FK_purchase_fees_purchase_id
SELECT 1
DROP TABLE OFFER CASCADE
DROP TABLE FEE CASCADE
DROP TABLE PURCHASE CASCADE
DROP TABLE offer_fees CASCADE
DROP TABLE purchase_fees CASCADE
CREATE TABLE OFFER (PRICE DECIMAL(13,3))
CREATE TABLE FEE (ID  SERIAL NOT NULL, RATE DECIMAL(8,4), PRIMARY KEY (ID))
CREATE TABLE PURCHASE (ID  SERIAL NOT NULL, PRICE DECIMAL(13,3), OFFER_ID BIGINT, PRIMARY KEY (ID))
CREATE TABLE offer_fees (offer_id BIGINT NOT NULL, fee_id BIGINT NOT NULL, PRIMARY KEY (offer_id, fee_id))
CREATE TABLE purchase_fees (purchase_id BIGINT NOT NULL, fee_id BIGINT NOT NULL, PRIMARY KEY (purchase_id, fee_id))
ALTER TABLE PURCHASE ADD CONSTRAINT FK_PURCHASE_OFFER_ID FOREIGN KEY (OFFER_ID) REFERENCES PURCHASE (ID)
ALTER TABLE offer_fees ADD CONSTRAINT FK_offer_fees_offer_id FOREIGN KEY (offer_id) REFERENCES PURCHASE (ID)
ALTER TABLE offer_fees ADD CONSTRAINT FK_offer_fees_fee_id FOREIGN KEY (fee_id) REFERENCES FEE (ID)
ALTER TABLE purchase_fees ADD CONSTRAINT FK_purchase_fees_fee_id FOREIGN KEY (fee_id) REFERENCES FEE (ID)
ALTER TABLE purchase_fees ADD CONSTRAINT FK_purchase_fees_purchase_id FOREIGN KEY (purchase_id) REFERENCES PURCHASE (ID)

1 Ответ

0 голосов
/ 16 августа 2020

Проблема может быть связана с генерацией схемы, чем-то связанным с Hibernate HBM.

Я воссоздал вашу модель классов, и Liquibase сгенерирует для нее правильную схему:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
    <changeSet author="(generated)" id="1">
        <createTable tableName="fee">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints primaryKey="true" primaryKeyName="feePK"/>
            </column>
            <column name="rate" type="DECIMAL(8, 4)"/>
        </createTable>
    </changeSet>
    <changeSet author="(generated)" id="2">
        <createTable tableName="offer">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints primaryKey="true" primaryKeyName="offerPK"/>
            </column>
            <column name="price" type="DECIMAL(13, 3)"/>
        </createTable>
    </changeSet>
    <changeSet author="(generated)" id="3">
        <createTable tableName="offer_fees">
            <column name="offer_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
            <column name="fee_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>
    <changeSet author="(generated)" id="4">
        <createTable tableName="purchase">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints primaryKey="true" primaryKeyName="purchasePK"/>
            </column>
            <column name="price" type="DECIMAL(13, 3)"/>
            <column name="offer_id" type="BIGINT"/>
        </createTable>
    </changeSet>
    <changeSet author="(generated)" id="5">
        <createTable tableName="purchase_fees">
            <column name="purchase_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
            <column name="fee_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>
    <changeSet author="(generated)" id="6">
        <addUniqueConstraint columnNames="fee_id" constraintName="UK_efbjp6b9dix0fvvu4ho4c23mx" tableName="offer_fees"/>
    </changeSet>
    <changeSet author="(generated)" id="7">
        <addUniqueConstraint columnNames="fee_id" constraintName="UK_l71j0m0qba02a1sd38km2c7rv" tableName="purchase_fees"/>
    </changeSet>
    <changeSet author="(generated)" id="8">
        <addForeignKeyConstraint baseColumnNames="offer_id" baseTableName="purchase" constraintName="FK8b5b4vp8smfuvge8vgx767b43" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="offer"/>
    </changeSet>
    <changeSet author="(generated)" id="9">
        <addForeignKeyConstraint baseColumnNames="purchase_id" baseTableName="purchase_fees" constraintName="FKjuwhxm0r6adifk562cy0wlgbv" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="purchase"/>
    </changeSet>
    <changeSet author="(generated)" id="10">
        <addForeignKeyConstraint baseColumnNames="fee_id" baseTableName="purchase_fees" constraintName="FKkmwtut3mhe5so6bhd55wslxja" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="fee"/>
    </changeSet>
    <changeSet author="(generated)" id="11">
        <addForeignKeyConstraint baseColumnNames="fee_id" baseTableName="offer_fees" constraintName="FKkp6c8xhv4mrqwbfwpcy5domyv" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="fee"/>
    </changeSet>
    <changeSet author="(generated)" id="12">
        <addForeignKeyConstraint baseColumnNames="offer_id" baseTableName="offer_fees" constraintName="FKmnqv7yujs8d1mddhtvmrn9cp" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="offer"/>
    </changeSet>
</databaseChangeLog>

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

...