1
votes

I have an entity manager repository, set up as follows:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(datasource());
    em.setJpaProperties(hibernateProperties(dynamicConfiguration));
    em.setPackagesToScan(new String[] {"<my model package>"});
    final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    return em;
}

My entity class is defined as follows:

@Entity
@Table(name = "model")
@Getter
@Setter
@NoArgsConstructor
public class Model {

@Column(name = "serialNumber")
private String serialNumber;

@Column(name = "region")
private String region;

@Column(name = "created")
private Date created;

@Column(name = "updated")
private Date updated;

@Column(name = "status")
private String status;


@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id")
private Long id;

}

My repository beans are like this:

@Repository
public interface ModelRepository extends JpaRepository<Model, Long>, ModelCustomRepository<Model, Long> {

}

My custom repository

@NoRepositoryBean
public interface ModelCustomRepository<E, L extends Number>{

List<Model> getModelsSkipUpdated();
}

My Custom repository implementation

public class ModelCustomRepositoryImpl implements ModelCustomRepository<Model, Long> {

@Autowired
private DynamicConfiguration dynamicConfiguration;

@Qualifier("entityManageFactory")
@Autowired
private EntityManagerFactory entityManagerFactory;

@Override
public List<Model> getModelsForProvisioning() {
    Integer limit = dynamicConfiguration.getIntProperty("model.limit", 25).get();
    Query modelQuery = entityManagerFactory.createEntityManager().createNativeQuery(
                    "SELECT * FROM Model WHERE status = :status LIMIT :limit for update skip locked",
                    Model.class);
    modelQuery.setParameter("status", NOT_PROCESSED.name());
    modelQuery.setParameter("limit", limit);
    return modelQuery.getResultList();
}
}

I get the below error, I don't get why I am getting the error

Caused by: java.lang.IllegalArgumentException: Not a managed type: class <package>.Model
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:472)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:73)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:181)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:119)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:102)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:298)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$3(RepositoryFactoryBeanSupport.java:287)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:141)
at org.springframework.data.util.Lazy.get(Lazy.java:63)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:290)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706)
... 54 more

I do not use spring-boot since this is an AWS lambda. Is there a way to work around this? Hence no @EntityScan.

My model class is not in the same package as the entity manager factory bean generation class.

On a side note, if there's a way to get the skip locked query within the @Repository bean, please let me know that as well.

1
Which database implementation are you using? (MySQL, PostgreSQL, etc)? For the Skip Locked, MySQL does not support it, but you can actually configure it with other DBMS if you are using Hibernate: docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/…. What you do is set PESSIMISTIC_WRITE LockMode with javax.persistence.lock.timeout = 2. As for the unmanaged exception, because you're not using Spring Boot, are you sure that you don't require a persistence.xml file describing your entities since you cannot use @EntityScan?Xaero Degreaz
We're using Postgres DB. Yeah, I can do the PESSIMISTIC_WRITE lock mode thing. With respect to persistence.xml, let me try it out and get back to you, might work. I wasn't sure it was necessary.Pavanraotk
Since I had the packages to scan in creating entitymanager, I thought that should suffice. Am I wrong? @XaeroDegreazPavanraotk
It's a good question to be honest -- I've never used any of this without using Spring Boot. I'm interested to learn myself (even though I'd probably never actually encounter this use case).Xaero Degreaz
I can't use spring-boot, since I have the context being created without spring-boot initializing it. Lambda starts and I have context initializers starting my spring context.Pavanraotk

1 Answers

2
votes

Per my comments on your question: Since you're unable to use @EntityScan, perhaps you need to provide a persistence.xml describing your entities.