Bug 414966 - @IdClass annotation wrongly required (@Id annotation present) using Table per tenant Multitenancy
Summary: @IdClass annotation wrongly required (@Id annotation present) using Table per...
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P2 critical with 9 votes (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: multitenancy
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-13 09:00 EDT by Andrea Lincetto CLA
Modified: 2022-06-09 10:19 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrea Lincetto CLA 2013-08-13 09:00:57 EDT
Using Eclipselink Version 2.4.2.v20130514-5956486

Given this example EclipseLink gives the following incorrect error; it seems like the @Id annotation is not read, so the code looks for the @IdClass annotation (but I've not a composite key)
Disabling multitenant capabilities, everythins works fine.

@Entity
@Table(name="CRS_MOMI_JOB")
@Multitenant(value=MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type=TenantTableDiscriminatorType.SCHEMA, contextProperty="eclipselink-tenant.id")
public class CrsMomiJob implements Serializable {
	@Id
	private BigDecimal id;		

	public CrsMomiJob() {
	}
	
	public BigDecimal getId() {
		return id;
	}

	public void setId(BigDecimal id) {
		this.id = id;
	}	
}

java.lang.IllegalArgumentException: No @IdClass attributes exist on the IdentifiableType [EntityTypeImpl@26762076:CrsMomiJob [ javaType: class com.xxxxxx.momi.model.core.CrsMomiJob descriptor: RelationalDescriptor(com.xxxxxx.momi.model.core.CrsMomiJob --> [DatabaseTable(CRS_MOMI_JOB)]), mappings: 7]].  There still may be one or more @Id or an @EmbeddedId on type.
	at org.eclipse.persistence.internal.jpa.metamodel.IdentifiableTypeImpl.getIdClassAttributes(IdentifiableTypeImpl.java:169)
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:170)
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:71)
	at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:146)
	at com.xxxxxx.momi.jpa.MultiTenantJpaRepositoryFactory.getTargetRepository(MultiTenantJpaRepositoryFactory.java:30)
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:67)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:136)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:153)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:43)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:109)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1448)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:910)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:853)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:314)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:910)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:853)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:505)
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
	at javax.servlet.GenericServlet.init(GenericServlet.java:244)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1453)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1250)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5093)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5380)
	at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2019)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1669)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:301)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:389)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:363)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291)
	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259)
	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461)
	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)
Comment 1 Andrea Lincetto CLA 2013-08-13 09:11:56 EDT
Seems to be a bug in the EclipseLink meta model code in hasSingleIdAttribute(), this is returning true (as the id is composite for multitenants) but this should be hidden, so should be returning false.
Comment 2 Tom Ware CLA 2013-08-19 10:13:39 EDT
Setting target and priority.  See the following page for the meanings of these fields:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines

Community: Please vote for this bug if it is important to you.  Votes are one of the main criteria we use to determine which bugs to fix next.
Comment 3 Andrea Lincetto CLA 2013-10-15 04:35:03 EDT
Any news about this bug?
I can work on it if someone point me to the right direction..
Comment 4 Ketan Prajapati CLA 2014-03-07 00:40:14 EST
I am using EclipseLink 2.5.1 and I am also facing this issue.

Please resolve it as I want Table Per Multi-Tenancy.

Thanks
Ketan
Comment 5 Andrea Lincetto CLA 2014-06-12 08:43:23 EDT
Yes, I updated to 2.5.1 and the problem still exist.
Comment 6 Andrea Lincetto CLA 2014-06-18 09:20:40 EDT
It seems that the exception is not thrown if the entity manager is instantiated with the tenant id in the properties map, e.g. TEN01 in my example :

        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan(/*you package*/);
        entityManagerFactoryBean.setPersistenceProviderClass(PersistenceProvider.class);
        entityManagerFactoryBean.setPersistenceUnitName("XXX");
        entityManagerFactoryBean.setLoadTimeWeaver(new ReflectiveLoadTimeWeaver());
        Properties jpaProperties = new Properties();
        jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, "Oracle");
        jpaProperties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, "TEN01");   
        jpaProperties.put(PersistenceUnitProperties.SESSION_NAME, "MoMi-" + UUID.randomUUID());
        entityManagerFactoryBean.setJpaProperties(jpaProperties);

So the exception is a little bit confusing, the cause is not the absence of IdClass annotation.
Comment 7 Study Hsueh CLA 2014-06-18 09:27:40 EDT
workaround method:
Just add a tenant-id property in persistence.xml such as
<property name="eclipselink.tenant-id" value="any" />

If not set the tenant-id property, it will make pkClass become null during initialization.
Comment 8 Pieter van Onselen CLA 2016-06-07 01:58:31 EDT
Please resolve this issues.

I am experiencing the same problem.  Workaround not acceptable.

When setting the initially causes EclipseLink not to change to another tenant at runtime:

        HashMap properties = new HashMap();
        properties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, TENANT_M_10001);
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAProject",properties);


This called after the first call does not change the tenant:

  EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAProject");
        EntityManager entityManager = emf.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, TENANT_M_10001);

        Vehicle vehicle = Vehicle.create(UUID.randomUUID(), "VIN7", 1,2,"BMW", UUID.randomUUID().toString(),null);
        vehicle.setUpholsteryCode("UPHO");
        entityManager.persist(vehicle);
        transaction.commit();
        entityManager.close();
Comment 9 Christoph Grimm CLA 2017-09-07 18:33:28 EDT
This Error still exist in version 2.6.4
I need as fast as possible a fix because i need this feature!
Comment 10 Christoph Grimm CLA 2017-09-24 15:27:00 EDT
Is this still a active forum?
Why does nobody respond to this?
This bug is 3-4 years old and essential for many business cases...

Thanks Christoph
Comment 11 Eclipse Webmaster CLA 2022-06-09 10:19:28 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink