简体   繁体   中英

org.hibernate.MappingException: Unknown entity on User object that contains Entity annotation

i am scratching my head wondering why this exception keeps popping up whenever i try to save a new user to my DB using spring and hibernate.

i have double checked and made sure @Entity annotation is present and even added @Table annoation to say which table this object belongs to and i am still recieving this error

below is my user object:

    @Entity
@Table(name = "USER")
public class User implements Serializable {

    /**
     * Serial version
     */
    private static final long serialVersionUID = 1L;

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_BIO = "Bio";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String SURNAME = "Surname";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_FIRST_NAME = "FirstName";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_PASSWORD = "Password";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_EMAIL = "EmailAddress";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_USERNAME = "Username";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_USER_ID = "UserId";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final int USERNAME_LENGTH = 5;

    @Id
    @Column(name = "USER_ID")
    @NotNull
    private String id;

    @Column(name = "USERNAME", nullable = false, unique = true)
    @NotNull
    private String username;

    @Column(name = "EMAIL_ADDRESS", nullable = false, unique = true)
    @NotNull
    private String emailAddress;

    @Column(name = "PASSWORD")
    @NotNull
    @Size(min = 5, max = 25)
    private String password;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "SURNAME")
    private String surname;

    @Column(name = "COUNTRY")
    private String country;

    @Column(name = "BIO")
    private String bio;



    @Column(name = "SESSION_ID")
    private String sessionId;

    @Column(name = "LAST_REST_CALL_MADE")
    private Date lastRestCallMade;

    @Column(name = "STATUS")
    @NotNull
    private int status;

    @OneToOne
    @JoinColumn(name = "imageId")
    private ProfileImage profileImage;

    public User() {
        id = UUID.randomUUID().toString();
    }

    @JsonElement(type = JsonElementType.GETTER)
    public ProfileImage getProfileImage() {
        return profileImage;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setProfileImage(ProfileImage profileImage) {
        this.profileImage = profileImage;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getId() {
        return id;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setId(String id) {
        this.id = id;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getUsername() {
        return username;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setUsername(String username) {
        this.username = username;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getEmailAddress() {
        return emailAddress;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getPassword() {
        return password;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setPassword(String password) {
        this.password = password;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getFirstName() {
        return firstName;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getSurname() {
        return surname;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setSurname(String surname) {
        this.surname = surname;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getBio() {
        return bio;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setBio(String bio) {
        this.bio = bio;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getCountry() {
        return country;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setCountry(String country) {
        this.country = country;
    }

    /**
     * @return the sessionId
     */
    public String getSessionId() {
        return sessionId;
    }

    /**
     * @param sessionId the sessionId to set
     */
    @JsonElement(type = JsonElementType.SETTER)
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    /**
     * @return the lastRestCallMade
     */
    public Date getLastRestCallMade() {
        return lastRestCallMade;
    }

    /**
     * @param lastRestCallMade the lastRestCallMade to set
     */
    public void setLastRestCallMade(Date lastRestCallMade) {
        this.lastRestCallMade = lastRestCallMade;
    }

    /**
     * @return the status
     */
    public int getStatus() {
        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(int status) {
        this.status = status;
    }

}

here is what my userDao does

@Override
    public void addNewUser(User user) throws InvalidDataException {
        // TODO: Add Transaction manager object here either using annototation
        // or creating it programatically

        if (mSessionFactory != null) {
            session = mSessionFactory.getCurrentSession();
            session.beginTransaction();
            if (user.getUsername() == null
                    || user.getUsername().length() < User.USERNAME_LENGTH) {
                throw new InvalidDataException(
                        InvalidDataException.ERROR_USERNAME_NULL);
            }

            session.save(user);

        }else{
            throw new RuntimeException("mSession is null");
        }
    }

pretty simple suff here.

full stracktrace below:

org.hibernate.MappingException: Unknown entity: com.jr.freedom.user.User
    at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1092)
    at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1399)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:753)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:745)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:741)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
    at $Proxy20.save(Unknown Source)
    at com.jr.freedom.dao.UserDao.addNewUser(UserDao.java:50)
    at com.jr.freedom.user.UserService.registerNewUser(UserService.java:47)
    at com.jr.freedom.controllers.UserController.createNewAccount(UserController.java:57)
    at com.test.jr.freedom.controllers.UserControllerTest.testCreateNewAccount(UserControllerTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

it crashes when i invoke session.save(user);

Bingo. here is the issue that lies on my xml config file that configures the sessionFactory:

<property name="annotatedClasses">
            <list>
                <value>com.jr.freedom.user.User</value>
                <value>com.jr.freedom.user.ProfileImage</value>
            </list>
        </property>

That was missing on this bean below:

<bean id="mySessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="configLocation" value="hibernate.cfg.xml" />
        <property name="annotatedClasses">
            <list>
                <value>com.jr.freedom.user.User</value>
                <value>com.jr.freedom.user.ProfileImage</value>
            </list>
        </property>

    </bean>

So i added that and it worked! question is, what if i have to maintain and use 100 of Entity's. it will be a chore creating a long list of annotatedClasses values inside this sessionFactory! Any idea how i can tell spring or hibernate to say " please scan through a selected package and find and use my Entity marked Objects ".

To answer question you posted in your answer.
You can use Entity Manager to autodetect hibernate entities.

The class element specifies a fully qualified class name that you will map. By default all properly annotated classes and all hbm.xml files found inside the archive are added to the persistence unit configuration. You can add some external entity through the class element though

. http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html

You can tell any JPA provider to scan a jar, but then you'd need to package all your entity classes in a separate jar. Any other solution is a provider specific hack. I did it by using google reflections to scan annotations and then use the EjbConfiguration class of Hibernate to register all entity annotated classes; but that is already deprecated in Hibernate 4 and is going to disappear in Hibernate 5.

I forgot to add my hbm.xml to my cfg.xml file. As soon as I added it, this exception disappeared.

<mapping resource="com/swipex/backend/hibernate/CServiceCenters.hbm.xml" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM