Provided id of the wrong type for class when testing

14,715

Solution 1

Your method is defined as

return em.find(Customer.class, Name);

EntityManager.find() takes the ID of an entity, and returns the entity that has that ID. The ID of Customer is a Long. It's not the name. You need a query to implement findByName().

Solution 2

I faced this problem and the cause was that I didn't specify 'Name' as an ID(a primary key) in my model. As a result the parameter I passed as Id was being compared with the system generated Id (hjid) of that Customer object, and ended up not finding the object with that system generated ID (which is long in type). So it is necessary to explicitly specify the desired primary key in the model.

Share:
14,715
Ru Ru
Author by

Ru Ru

Updated on July 05, 2022

Comments

  • Ru Ru
    Ru Ru almost 2 years

    I have got this issue when testing- Provided id of the wrong type for class com.myapp.ibank.domain.Customer. Expected: class java.lang.Long, got class java.lang.String

    And I honestly cant figure out why I have got this and what is actually happening. When I use it normally, like running on a local tomcat and saving it through a controller and then service, it works just fine. No errors. This behaviour makes no sense to me.

    I am using JPA 2.1 with Hibernate as a provider.

    Here is test code:

    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    @ContextHierarchy({
            @ContextConfiguration(classes = RootConfig.class),
            @ContextConfiguration(classes = WebConfig.class)
    
    })
    @Transactional
    public class AccountRepositoryTest {
    
        @Autowired
        private WebApplicationContext wac;
        @Autowired
        private AccountRepository accountRepository;
        @Autowired
        private CustomerService customerService;
    
        private MockMvc mockMvc;
    
        @Before
        public void setup() {
            this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    
            Customer cus = new Customer();
            cus.setFirstName("John");
            cus.setLastName("Smith");
            customerService.save(cus);
        }
    
        @Test
        public void testSaveAccount() {
    
            Account account = new Account();
            account.setCustomer(customerService.findByName("John"));
            account.setName();
            account.setDebitCard(new DebitCard((long) 2000));
    
            accountRepository.create(account);
        }
    
        @Test
        public void testSavePremiumAccount() {
    
            PremiumAccount premAccount = new PremiumAccount();
            premAccount.setCustomer(customerService.findByName("John"));
            premAccount.setName();
            premAccount.setDebitCard(new DebitCard((long) 6000));
            premAccount.setCreditCard(new CreditCard((long) 12000));
    
            accountRepository.create(premAccount);
        }
    
    }
    

    My Customer Entity (Short version):

    @Entity
    @DynamicUpdate
    @Table(name = "customer")
    public class Customer implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String firstName;
        private String lastName;
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "customer")
        //@JoinColumn(name="account_id", referencedColumnName="id")
        @Nullable
        @JsonManagedReference
        private List<Account> Accounts = new ArrayList<Account>();
        //private Address Address;
    
    
        public Customer() {
        }
    
        public Customer(String firstName, String lastName,  List<Account> accounts) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.Accounts = accounts;
        }
    

    And my repo:

    @Repository("customerRepository")
    public class CustomerRepositoryImpl implements CustomerRepository {
    
        @PersistenceContext
        private EntityManager em;
    
    
        @Override
        @Transactional
        @NotNull
        public void save(Customer customer) {
            em.persist(customer);
            em.flush();
        }
    
        @Override
        public Customer findByName(String Name) {
        return em.find(Customer.class, Name);
        }
    }
    

    What do I miss, or is this a general bug with the hibernate that cant be avoided? I read somewhere that this is a typical bug.

    Full Stack Trace:

    org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class com.ruruapps.ibank.domain.Customer. Expected: class java.lang.Long, got class java.lang.String; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.ruruapps.ibank.domain.Customer. Expected: class java.lang.Long, got class java.lang.String
        at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:157)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
        at com.sun.proxy.$Proxy45.findByName(Unknown Source)
        at com.ruruapps.ibank.service.CustomerServiceImpl.findByName(CustomerServiceImpl.java:40)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
        at com.sun.proxy.$Proxy48.findByName(Unknown Source)
        at com.ruruapps.ibank.AccountRepositoryTest.testSaveAccount(AccountRepositoryTest.java:55)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
        at org.junit.runners.Suite.runChild(Suite.java:127)
        at org.junit.runners.Suite.runChild(Suite.java:26)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
    Caused by: java.lang.IllegalArgumentException: Provided id of the wrong type for class com.ruruapps.ibank.domain.Customer. Expected: class java.lang.Long, got class java.lang.String
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1135)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1068)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
        at com.sun.proxy.$Proxy44.find(Unknown Source)
        at com.ruruapps.ibank.repository.CustomerRepositoryImpl.findByName(CustomerRepositoryImpl.java:47)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        ... 59 more
    Caused by: org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.ruruapps.ibank.domain.Customer. Expected: class java.lang.Long, got class java.lang.String
        at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:134)
        at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1106)
        at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:176)
        at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2587)
        at org.hibernate.internal.SessionImpl.get(SessionImpl.java:991)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1110)
        ... 75 more
    

    Customer Service Impl:

    @Service("customerService")
    @Transactional
    public class CustomerServiceImpl implements CustomerService {
    
        @Autowired
        private CustomerRepository customerRepository;
    
        @Override
        public void save(Customer customer) {
            customerRepository.save(customer);
        }
    
        @Override
        public List<Customer> findAll() {
            return customerRepository.findAll();
        }
    
        @Override
        public Customer findById(Long id) {
            return customerRepository.findById(id);
        }
    
        @Override
        public Customer findByName(String Name) {
            return customerRepository.findByName(Name);
        }
    }