簡體   English   中英

如何在Spring Boot中完全禁用Hibernate異常

[英]how to completely disable Hibernate exceptions within Spring Boot

我有情況 我正在創建一個Spring Boot項目,以與大量舊版OpenJPA實體進行交互。

問題是,由於Spring Boot Starter Data JPA使用Hibernate作為基礎,因此Spring應用程序會拋出Hibernate異常,例如:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]
: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: 
Using default @DiscriminatorValue for a discriminator of type CHAR is not safe

現在, 盡管可以通過更新實體代碼輕松解決此問題,但我們無法觸摸或更改該代碼 我們必須保持現狀-不符合Hibernate標准。

那么,在Spring內是否有任何方法可以禁用Hibernate異常,這樣我們可以接受不符合Hibernate標准的實體並拋出Hibernate異常?

我們的代碼設計很簡單,是標准的服務庫設置。 例如:

PersonRepository.java:

public interface PersonRepository extends CrudRepository<Person, Long> {

    Person findFirstByPersonSsnSsn(String ssn);

    Person findFirstByPersonId(Integer personId);

}

PersonDomainService.java:

public interface PersonDomainService {

    Person findPersonBySsn(String ssn); 

    public Person findPerson(Integer id);
}

PersonDomainServiceImpl.java:

@Service
@Transactional
public class PersonDomainServiceImpl implements PersonDomainService {

    private PersonRepository personRepository;

    @Autowired
    public PersonDomainServiceImpl(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @Transactional(readOnly=true)
    public Person findPersonBySsn(String ssn) {
        Person person = personRepository.findFirstByPersonSsnSsn(ssn);

        System.out.println(person.getAddresses().size());
        System.out.println(person.getPhones().size());

        return person;

    }

    @Transactional(readOnly=true)
    public Person findPerson(Integer id) {
        // TODO Auto-generated method stub
        Person person = personRepository.findFirstByPersonId(id);

        System.out.println(person.getAddresses().size());
        System.out.println(person.getPhones().size());

        return person;
    }   
}

實體是非常標准的:

@Entity
@Table(name = "PERSON", schema = "SCHEMA")
public class Person implements Serializable, EntityWithAuditInfo {
...

異常表明休眠狀態拒絕初始化自己,因此這不是一個異常處理問題,但是您必須以某種方式說服休眠狀態,即使感覺歧視者是“危險的”。

搜索休眠的源代碼顯示此異常被拋出

public void bindDiscriminatorValue() {
    if ( StringHelper.isEmpty( discriminatorValue ) ) {
        Value discriminator = persistentClass.getDiscriminator();
        if ( discriminator == null ) {
            persistentClass.setDiscriminatorValue( name );
        }
        else if ( "character".equals( discriminator.getType().getName() ) ) {
            throw new AnnotationException(
                    "Using default @DiscriminatorValue for a discriminator of type CHAR is not safe"
            );
        }
        else if ( "integer".equals( discriminator.getType().getName() ) ) {
            persistentClass.setDiscriminatorValue( String.valueOf( name.hashCode() ) );
        }
        else {
            persistentClass.setDiscriminatorValue( name ); //Spec compliant
        }
    }
    else {
        //persistentClass.getDiscriminator()
        persistentClass.setDiscriminatorValue( discriminatorValue );
    }
}

如您所見,如果未為char類型的鑒別符提供discriminatorValue,則休眠狀態將始終拋出此類異常。 沒有任何辦法可以避免更改用於休眠的源代碼的不足。

此方法以下方法調用

public void bindEntity() {
    persistentClass.setAbstract( annotatedClass.isAbstract() );
    persistentClass.setClassName( annotatedClass.getName() );
    persistentClass.setJpaEntityName(name);
    //persistentClass.setDynamic(false); //no longer needed with the Entity name refactoring?
    persistentClass.setEntityName( annotatedClass.getName() );
    bindDiscriminatorValue();

    persistentClass.setLazy( lazy );
    if ( proxyClass != null ) {
        persistentClass.setProxyInterfaceName( proxyClass.getName() );
    }
    persistentClass.setDynamicInsert( dynamicInsert );
    persistentClass.setDynamicUpdate( dynamicUpdate );

    ... and 170 more lines of code to parse all other annotations in this class
}

正如我們從沒有catch塊的情況可以看到的那樣,如果無法確定鑒別器值,休眠將中止對該實體的解析。

因此,當鑒別符為char類型時,即使最新版本的休眠也無法與缺少鑒別符值的實體一起使用。 (順便說一句,這有一個未解決的問題 ,冬眠團隊在過去的7年中沒有對此采取行動。)

解決此問題的唯一方法是更改​​實體,更改休眠或使用其他JPA實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM