org.hibernate.MappingException: Unknown entity: annotations.Users
Asked Answered
G

23

46

Consider the hierarchy :

enter image description here

And the following classes and xml :

HibernateUtil.java

package annotations;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;


/**
 * 
 * @author X3
 *
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();
    private static final String HIBERNATE_CFG = "hibernateAnnotations.cfg.xml";

    private static SessionFactory buildSessionFactory() 
    {
        Configuration cfg = new Configuration().addResource(HIBERNATE_CFG).configure();
        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().
                applySettings(cfg.getProperties()).buildServiceRegistry();
        SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
        return sessionFactory;
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Users.java

package annotations;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;

@Entity
@Table(name = "Users")
public class Users {

    @Id
    @GeneratedValue
    @Column(name = "USER_ID")
    private long userID;

    @Column(name = "USERNAME", nullable = false, length = 100)
    private String username;

    @Column(name = "MessageTimeDate", nullable = false)
    private java.sql.Timestamp datetime;

    @Column(name = "UserMessage", nullable = false)
    private String message;



    public Users(String username , String message)
    {
        java.util.Date date = new java.util.Date();
        this.datetime = new Timestamp(date.getTime());

        this.username = username;
        this.message = message;
    }

    public long getUserID() {
        return userID;
    }

    public void setUserID(long userID) {
        this.userID = userID;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public java.sql.Timestamp getDatetime() {
        return datetime;
    }

    public void setDatetime(java.sql.Timestamp datetime) {
        this.datetime = datetime;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

Main.java

package annotations;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

    public static void main(String[] args) {

        try
        {
               SessionFactory sf = HibernateUtil.getSessionFactory();
               Session session = sf.openSession();
               session.beginTransaction();

               Users user1 = new Users("Jack" , "Hello");
               session.save(user1);
               session.getTransaction().commit();
               session.close();
        }

        catch (Exception e)
        {
            System.out.println(e.toString());
            e.getStackTrace();
        }


    }
}

And hibernateAnnotations.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/CHAT_DB</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">1</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <mapping class="annotations.Users"></mapping>       
    </session-factory>
</hibernate-configuration>

When I run main(), the following error appears in output window :

org.hibernate.MappingException: Unknown entity: annotations.Users

But the entity Users is in annotations package , so what's wrong ?

Golem answered 22/4, 2014 at 8:34 Comment(1)
Could you commit the considered structure to the github or some other online source repository so we could check it out and try running?Janssen
D
88

The Hibernate configuration file must define the entity classes:

<mapping class="annotations.Users"/>

Or you must explicitly add the class to the configuration using

configuration.addClass(annotations.Users.class)
// Read mappings as a application resourceName
 // addResource is for add hbml.xml files in case of declarative approach
configuration.addResource("myFile.hbm.xml");  // not hibernateAnnotations.cfg.xml
Demetria answered 22/4, 2014 at 9:28 Comment(7)
This is very weird , since it makes me to use another XML file , where the entire idea of Hibernate Annotations is to avoid them , except using the hibernateAnnotations.cfg.xml , of course .Golem
@ron addresource method is used for hbm files not for hibernate configuration cfg.xml file, if you are using declarative approach then you should use this other wise not. No need of this method if you are using annotation approcahDemetria
I already have this : <mapping class="annotations.Users"/> in hibernateAnnotations.cfg.xml , still same result .Golem
plus one, adding "<mapping resource="myFile.hbm.xml"/>" in hibernate.cfg.xml also workedFinding
if you can't get it to work in hibernate.cfg.xml, try configuration.addAnnotatedClass NOT configuration.addClassJeffrey
@Jeffrey This also worked for me. Much appreciated.Metalware
You can't make it run directly by using code mentioned in the answer, you have to follow comment of @OneSolitaryNoob. Thanks btw.Arizona
R
17

When I was trying to rewrite my example (from tutorialspoint) to use annotations, I got the same exception. This helped me (addAnnotatedClass()):

Configuration cfg=new Configuration(); 
cfg.addAnnotatedClass(com.tutorialspoint.hibernate.entity.Employee.class);
cfg.configure();
Reorder answered 29/12, 2015 at 21:12 Comment(2)
Given that the Entity class is annotated this is the correct answer - question mentions no hbm.xml fileOneidaoneil
@Jeffrey mentioned it above as well but this worked for me. Many thanks.Metalware
H
13

I did not find the accepted answer helpful in resolving the exception encountered in my code. And while not technically incorrect, I was also not satisfied with others' suggestions to introduce redundancy:

  • programmatically re-add the mapped class using configuration.addAnnotatedClass(...)
  • create a hbm.xml file and resource mapping in hibernate_test.cfg.xml that were redundant to the existing annotations
  • scan the package where the (already mapped) class exists using external dependencies not mentioned in the original question

However, I found 2 possible solutions that I wanted to share, both of which independently resolved the exception I encountered in my own code.

I was having the same MappingException as @ron (using a very nearly identical HibernateUtil class):

public final class HibernateUtil {

    private static SessionFactory sessionFactory = null;
    private static ServiceRegistry serviceRegistry = null;

    private HibernateUtil() {}

    public static synchronized SessionFactory getSessionFactory() {
        if ( sessionFactory == null ) {
            Configuration configuration = new Configuration().configure("hibernate_test.cfg.xml");
            serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .build();
            sessionFactory = configuration.buildSessionFactory( serviceRegistry );
        }
        return sessionFactory;
    }
// exception handling and closeSessionFactory() omitted for brevity
}

Within my hibernate_test.cfg.xml configuration file, I have the required class mapping:

<mapping class="myPackage.Device"/>

And my Device class is properly annotated with the javax.persistence.Entity annotation:

package myPackage.core;
import javax.persistence.*;

@Entity
@Table( name = "devices" )
public class Device {
    //body omitted for brevity
}

Two Possible Solutions:

First, I am using Hibernate 5.2, and for those using Hibernate 5 this solution using a Metadata object to build a SessionFactory should work. It also appears to be the currently recommended native bootstrap mechanism in the Hibernate Getting Started Guide :

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        serviceRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate_test.cfg.xml")
                .build();

        sessionFactory = new MetadataSources( serviceRegistry )
                    .buildMetadata()
                    .buildSessionFactory();
    }
    return sessionFactory;
}

Second, while Configuration is semi-deprecated in Hibernate 5, @ron didn't say which version of Hibernate he was using, so this solution could also be of value to some.

I found a very subtle change in the order of operations when instantiating and configuring Configuration and ServiceRegistry objects to make all the difference in my own code.

Original order (Configuration created and configured prior to ServiceRegistry):

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        Configuration configuration = new Configuration().configure("hibernate_test.cfg.xml");

        serviceRegistry = new StandardServiceRegistryBuilder()
                .applySettings( configuration.getProperties() )
                .build();

        sessionFactory = configuration.buildSessionFactory( serviceRegistry );
    }
    return sessionFactory;
}

New order (ServiceRegistry created and configured prior to Configuration):

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        serviceRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate_test.cfg.xml")
                .build();

        sessionFactory = new Configuration().buildSessionFactory( serviceRegistry );
    }
    return sessionFactory;
}

At the risk of TLDR, I will also point out that with respect to hibernate_test.cfg.xml my testing suggests that the configuration.getProperties() method only returns <property /> elements, and <mapping /> elements are excluded. This appears consistent with the specific use of the terms 'property' and 'mapping' within the API documentation for Configuration. I will concede that this behaviour may have something to do with the failure of applySettings() to yield the mapping data to the StandardServiceRegistryBuilder. However, this mapping data should already have been parsed during configuration of the Configuration object and available to it when buildSessionFactory() is called. Therefore, I suspect this may be due to implementation-specific details regarding resource precedence when a ServiceRegistry is passed to a Configuration object's buildSessionFactory() method.

I know this question is several years old now, but I hope this answer saves somebody the hours of research I spent in deriving it. Cheers!

Haven answered 25/1, 2018 at 2:3 Comment(1)
+1; I don't understand why your answer has not been appreciated! It gave me some valuable insight in a similar problem I was having. Thanks.Shawannashawl
M
7

Add the following to your xml:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>annotations</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
Metralgia answered 14/1, 2015 at 2:10 Comment(1)
I tried 1000... solutions suggested in a lot of posts...this is the one that worked for me. tnks!Overseer
H
6

I was having same problem.

Use @javax.persistence.Entity instead of org.hibernate.annotations.Entity

Heritable answered 12/3, 2016 at 17:38 Comment(0)
K
5

For those using Spring's Java configuration classes, you might write the following:

@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
    LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
    sessionBuilder.addProperties(getHibernateProperties());
    sessionBuilder.addAnnotatedClasses(Foo.class);
    sessionBuilder.addAnnotatedClasses(Bar.class);
    sessionBuilder.addAnnotatedClasses(Bat.class);
    return sessionBuilder.buildSessionFactory();
}
Kumamoto answered 8/5, 2015 at 7:48 Comment(1)
Good answer, alternatively, if your entities are located in the same package/sub-packages, you could take advantage of the "scanPackages" method instead of adding the entities one by one. sessionBuilder.scanPackages("com.example.entities"); More info : docs.spring.io/spring/docs/current/javadoc-api/org/…Hock
C
4

If your entity is mapped through annotations, add the following code to your configuration;

configuration.addAnnotatedClass(theEntityPackage.EntityClassName.class);

For example;

configuration.addAnnotatedClass(com.foo.foo1.Products.class);

if your entity is mapped with xml file, use addClass instead of addAnnotatedClass.

As an example;

configuration.addClass(com.foo.foo1.Products.class);

Ping me if you need more help.

Carduaceous answered 13/6, 2017 at 14:59 Comment(0)
L
3

I was facing the same issue and I searched for almost 2 hours and tried with different possible ways like replacing old hibernate JARs and changing the DB table schema. But finally got the solution as below:

SessionFactory factory = new Configuration().configure().buildSessionFactory(); //This line to be replaced with below commented line

Replace above for

//Configuration config = new Configuration().configure();
//ServiceRegistry servReg = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//SessionFactory factory = config.buildSessionFactory(servReg);

It will then work fine..

Lidstone answered 4/7, 2017 at 5:53 Comment(0)
C
1

Instead of using HibernateUtil.java, to create sessionfactory object, you should use this:

SessionFactory sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory();

Because in order to avoid the exception, you'll have to declare the class object in HibernateUtil.java file as configuration.addAnnotatedClass(Student_Info.class); which looks dumb because we have provided the entry already in hibernate.cfg.xml file.

To use the AnnotationConfiguration class you'll have to add a jar to your project build path: http://www.java2s.com/Code/Jar/h/Downloadhibernate353jar.htm

Compare answered 5/9, 2016 at 11:7 Comment(0)
T
1

I was having similar issue and adding

 sessionFactory.setAnnotatedClasses(User.class);

this line helped but before that I was having

sessionFactory.setPackagesToScan(new String[] { "com.rg.spring.model" });

I am not sure why that one is not working.User class is under com.rg.spring.model Please let me know how to get it working via packagesToScan method.

Trudi answered 27/7, 2017 at 15:30 Comment(0)
Z
0

Define the Entity class in Hibernate.cfg.xml

<mapping class="com.supernt.Department"/>

While creating the sessionFactory object Load the Configuration file Like

SessionFactory factory = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
Zildjian answered 30/7, 2015 at 2:18 Comment(1)
Thanks, I was also missing mapping tag in my configuration file.Pelletier
T
0
 public static void main(String[] args) {
      try{
        // factory = new Configuration().configure().buildSessionFactory();
         factory = new AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   buildSessionFactory();
      }catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }//you can write like this in your test class inside main method.this way you will be able to do the things using annotaions only
Trilbee answered 29/12, 2016 at 7:45 Comment(0)
P
0

Add the following code to hibernate.cfg.xml

  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>
  <property name="hibernate.c3p0.timeout">300</property>
  <property name="hibernate.c3p0.max_statements">50</property>
  <property name="hibernate.c3p0.idle_test_period">3000</property>
Palaeontography answered 21/4, 2017 at 11:56 Comment(0)
W
0

Check the package name is given in the property packagesToScan in the dispatcher-servlet.xml

<bean id="sessionFactory"             class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <property name="packagesToScan" value="**entity package name here**"></property> 
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>  
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>  
            </props>  
        </property>  
    </bean>
Whelp answered 6/11, 2017 at 5:42 Comment(0)
M
0

Use EntityScanner if you can bear external dependency.It will inject your all entity classes seamlessly even from multiple packages. Just add following line after configuration setup.

Configuration configuration = new Configuration().configure();    
EntityScanner.scanPackages("com.fz.epms.db.model.entity").addTo(configuration);
// And following depencency if you are using Maven
<dependency>
        <groupId>com.github.v-ladynev</groupId>
        <artifactId>fluent-hibernate-core</artifactId>
        <version>0.3.1</version>
</dependency>

This way you don't need to declare all entities in hibernate mapping file.

Mucor answered 9/1, 2018 at 20:19 Comment(0)
D
0

If you are using 5.0x version,configuration with standard service registry is deprecated.

Instead you should bootstrap it with Metadata: In your HibernateUtil class, you should add

private static SessionFactory buildSessionFactory() {
    try {           
        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
            .configure( "hibernate.cfg.xml" )
            .build();

        Metadata metadata = new MetadataSources( standardRegistry )
            .getMetadataBuilder()
            .build();

        return metadata.getSessionFactoryBuilder().build();
    } catch(...) {
        ...
    }
}
Delapaz answered 29/9, 2018 at 14:7 Comment(0)
A
0

In my case it resolves by adding configuration.addAnnotatedClass(com.myApp.model.Example.class); after Configuration configuration = new Configuration().configure(HibernateUtil.class.getResource("/hibernate.cfg.xml")); in hibernateUtill class. It Read a mapping from the class annotation metadata . Read more about addAnnotatedClass() from here.

Acidulant answered 25/7, 2019 at 13:44 Comment(0)
P
0

Initially I trying with the below code which didn't work for me

MetadataSources metadataSources = new MetadataSources(serviceRegistry);
Metadata metadata = metadataSources.getMetadataBuilder().build();
SessionFactory sessionFactory= metadata.getSessionFactoryBuilder().build();

For me below configuration worked. All the hibernate properties i provided from the code itself and using hibernate version 5+. I'm trying to connect to the Postgressql db.

imports:

 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.Transaction;
 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.cfg.Environment;
 import org.hibernate.service.ServiceRegistry;

code:

    Configuration configuration = new Configuration();
    configuration.setProperty("hibernate.current_session_context_class", "thread");
    configuration.setProperty(Environment.DRIVER, "org.postgresql.Driver");
    configuration.setProperty(Environment.URL, lmsParams.getDbProperties().getDbURL());
    configuration.setProperty(Environment.USER, lmsParams.getDbProperties().getUsername());
    configuration.setProperty(Environment.PASS, lmsParams.getDbProperties().getPassword());

    configuration.setProperty("hibernate.connection.release_mode", "auto");
    configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
    configuration.setProperty("hibernate.show_sql", "true");
    configuration.setProperty(Environment.HBM2DDL_AUTO, "create");
    configuration.addAnnotatedClass(LMSSourceTable.class);
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties())
            .build();
    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

Latest Update: One more option worked for me using the Reflections package as a dependency. This i tried with both mysql and postgress and it works fine.

Some info about Reflections: The Reflections library works as a classpath scanner. It indexes the scanned metadata and allows us to query it at runtime. It can also save this information, so we can collect and use it at any point during our project, without having to re-scan the classpath again

if you are using maven:

<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>

code:

 MetadataSources metadataSources = new 
 MetadataSources(serviceRegistry);
 Reflections entityPackageReflections = new Reflections("com.company.abc.package.name");
    entityPackageReflections.getTypesAnnotatedWith(Entity.class).forEach(metadataSources::addAnnotatedClass);
    Metadata metadata = metadataSources.getMetadataBuilder().build();
    SessionFactory sessionFactory=  metadata.getSessionFactoryBuilder().build();
Polymerization answered 27/12, 2019 at 1:18 Comment(0)
L
0

I had the same error and the only thing that worked for me was to change the location of hibernate.cfg.xml to src/main/resources

Lottie answered 8/4, 2021 at 6:54 Comment(0)
I
0

I fix this error by add in the .xml configuration property name="packagesToScan" with value="SCANN_YOUR_PACKAGE.controller.entity" to show a Hibernate where is the package of entity's.

<!--  Configu Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="SCANN_YOUR_PACKAGE.controller.entity" />
        <property name="hibernateProperties">
           <props>
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
              <prop key="hibernate.show_sql">true</prop>
           </props>
        </property>
   </bean>  
Impel answered 18/5, 2021 at 9:35 Comment(0)
R
0

@Entity is deprecated then **error shows Exception in thread "main" org.springframework.orm.hibernate5.HibernateSystemException: Unknown entity: com.spring.orm.entities.Student; nested exception is org.hibernate.MappingException: Unknown entity: com.spring.orm.entities.Student **

My Code is

package com.spring.orm.entities;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Entity;

@Entity
@Table(name = "student_details")
public class Student {

    @Id
    @Column(name = "student_id")
    private int studentId;
    @Column(name = "student_name")
    private String studentName;
    @Column(name = "student_city")
    private String studentCity;

    public Student(int studentId, String studentName, String studentCity) {
        super();
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentCity = studentCity;
    }

    public Student() {

    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentCity() {
        return studentCity;
    }

    public void setStudentCity(String studentCity) {
        this.studentCity = studentCity;
    }

}

You can use @javax.persistence.Entity in place of @Entity

    package com.spring.orm.entities;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Entity;

@javax.persistence.Entity
@Table(name = "student_details")
public class Student {

    @Id
    @Column(name = "student_id")
    private int studentId;
    @Column(name = "student_name")
    private String studentName;
    @Column(name = "student_city")
    private String studentCity;

    public Student(int studentId, String studentName, String studentCity) {
        super();
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentCity = studentCity;
    }

    public Student() {

    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentCity() {
        return studentCity;
    }

    public void setStudentCity(String studentCity) {
        this.studentCity = studentCity;
    }

}

For more details you can see on my youtube channel https://youtu.be/uwLU65E4q3Y

Robbins answered 10/10, 2021 at 8:13 Comment(0)
A
0

The exception occurs because hibernate can locate mapping file (someEntity.hbm.xml)

One of the solution is to add hbm xml file to configuration while generating session factory.

configuration.addResource("someEntity.hbm.xml");
Altar answered 29/1, 2022 at 19:45 Comment(0)
H
-1

Problem occurs because of the entry mapping class="annotations.Users" in hibernate.cfg.xml remove that line then it will be work.

I had the same issue. When I removed the above line then it was working fine for me.

Halftone answered 4/5, 2016 at 8:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.