Как Hibernate JPA @JoinColumn (nullable = false) может генерировать ТОЛЬКО ограничение базы данных, в частности, в одном методе @ManyToOne - PullRequest
0 голосов
/ 29 января 2019

Это не повторяющаяся проблема, другие не имеют такой же сценарий

Моя проблема похожа на этот комментарий: nullable = false не только создает ограничение базы данных, но его решение отключает все проверки обнуляемости из спящего режима, чего я не хочу, я хочу именно это в этих отношениях @ManyToOne.

У меня есть класс RegraValidacao.java, который иногда может иметь только одиниз его полей @ManyToOne установлено, остальные нулевые.Эти отношения @ManyToOne создаются с помощью @JoinTable.То, что я хочу: при генерации моего DDL с помощью spring.jpa.properties.hibernate.hbm2ddl.auto , я хочу, чтобы @JoinColumns, присутствующая в аннотации @JoinTable, генерировала ограничение базы данных NOT NULL только для моей базы данных db2.

Таким образом, RegraValidacao может иметь @ManyToOne обнуляемые отношения с сущностями ContaLimite.java и Documento.java.Все будет в порядке, чтобы сохранить RegraValidacao, который имеет только ContaLimite.java, например:

RegraValidacao rgr = new RegraValidacao();
rgr.setContaLimite(new ContaLimite());
rgr.setDocumento(null);

hibernate.save(rgr) // SHOULD WORK

Но когда я установлю nullable = false на моем JoinColumn, он не позволитполе Documento должно быть нулевым.

@Entity
public class RegraValidacao {

    @ManyToOne
    @JoinTable(name = "CDR_CONTA_LIMITE_REGRA", 
    joinColumns = {@JoinColumn(name = "RGR_ID", nullable = false)},
    inverseJoinColumns = {@JoinColumn(name = "CDL_ID", nullable = false)})
    private ContaLimite contaLimite;

    @ManyToOne
    @JoinTable(name = "DOR_DOCUMENTO_REGRA",
    joinColumns = {@JoinColumn(name = "RGR_ID", nullable = false)}, 
    inverseJoinColumns = {@JoinColumn(name = "DOM_ID", nullable = false)})
    private Documento documento;
}

РЕДАКТИРОВАТЬ: Для упрощения я просто поместил эти два атрибута, но на самом деле у меня есть 8 пар Attributtes / JoinTables в этом классе.И почему?Потому что эти отношения взаимно исключены.Если бы у меня были общие табличные отношения @ManyToOne без JoinTables, у меня было бы 7 пустых полей в базе данных и 1 набор.С JoinTables у меня не будет пустых полей, и если в JoinTable установлен идентификатор, то, безусловно, есть запись в связанных таблицах.

Другими словами, связь с ContaLimite.java и Documento.java должнаbe: необязательный = true, но их столбцы в @JoinTable должны иметь значение nullable = false.

Что я ожидаю: Таблицы, созданные с помощью hbm2ddl.auto:

CDR_CONTA_LIMITE_REGRA --> RGR_ID NOT NULL, CDL_ID NOT NULL //OK
DOR_DOCUMENTO_REGRA --> RGR_ID NOT NULL, CDL_ID NOT NULL //OK

Сохранение с помощью Hibernate:

RegraValidacao rgr = new RegraValidacao();
rgr.setContaLimite(new ContaLimite());
rgr.setDocumento(null);

hibernate.save(rgr) // SHOULD BE OK!

Что я получаю: Таблицы, созданные с помощью hbm2ddl.auto:

CDR_CONTA_LIMITE_REGRA --> RGR_ID NOT NULL, CDL_ID NOT NULL //OK
DOR_DOCUMENTO_REGRA --> RGR_ID NOT NULL, CDL_ID NOT NULL //OK

Сохранение с помощью Hibernate:

RegraValidacao rgr = new RegraValidacao();
rgr.setContaLimite(new ContaLimite());
rgr.setDocumento(null);

hibernate.save(rgr) --> Error, cannot persist null

ERROR: org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : br.system.regravalidacao.RegraValidacao.documento; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : br.system.regravalidacao.RegraValidacao.documento

Таким образом, я ожидаю, что столбцы JoinTable будут иметь ограничение NOT NULL, но я все еще могу сохранить RegraValidacao с нулевым Documento.

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Ну, я нашел решение, которое подходит, но это не совсем то, что я хотел.Надеюсь, что когда-нибудь это кому-нибудь поможет.

Я хотел отключить проверку нуля в Hibernate Runtime для определенного атрибута класса, чего я не смог достичь.Я мог бы просто отключить его для всего своего класса. RegraValidacao.java

Я создал пакет класса Spring @Configuration с файлом .properties (внутри моего каталога / resources) с spring.jpa.properties.hibernate..check_nullability = false на нем и @ComponentScan для моего пакета класса:

RegraValidacaoConfiguration.java:

@Configuration
@PropertySource("classpath:regravalidacao.properties")
@EntityScan(RegraValidacaoConfiguration.PACKAGE)
@ComponentScan({RegraValidacaoConfiguration.PACKAGE})
class RegraValidacaoConfiguration {
    static final String PACKAGE = "br.system.regravalidacao";
}

RegraValidacao.java:

package br.system.regravalidacao;
public class RegraValidacao {
    //...
}

regravalidacao.properties:

spring.jpa.properties.hibernate.check_nullability=false

Таким образом, весь мой проект все равно будет иметь spring.jpa.properties.hibernate.check_nullability = true (по умолчанию) и только мой пакет br.system.regravalidacao будет ложным.

Единственная травма - мои другие атрибуты внутри RegraValidacao (некоторые из них @OneToOne) будут ошибочно затронуты check_nullability = false, поэтому я хотел что-то для атрибута, а не для класса.Хотя эта травма не так уж и плоха, потому что я все равно получу сообщение об ошибке этих атрибутов не из Hibernate Runtime, а из моей базы данных.Это довольно хорошо для меня.

0 голосов
/ 29 января 2019

Вы используете свою таблицу соединений для двух атрибутов.Я бы не рекомендовал это.

Если я правильно понимаю ваш вопрос, вы хотите, чтобы либо Documento был нулевым, либо было задано либо Documento, либо ContaLimite.Поэтому я бы просто разрешил null для Documento.

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