Showing posts with label postgresql. Show all posts
Showing posts with label postgresql. Show all posts

Monday, 15 June 2026

Install PostgreSQL in Mac

Setting up PostgreSQL locally on macOS is straightforward, but doing it correctly (with proper users, passwords, and security) makes a big difference, especially if you’re building backend systems or data platforms.

 

This guide walks you through:

 

·      Installation

·      Starting the database

·      Creating users and passwords

·      Securing access

·      Best practices

 

1. Install PostgreSQL on macOS

Install PostgreSQL by executing following command.

brew install postgresql

 

Start PostgreSQL

brew services start postgresql

 

Verify installation by executing below command

psql --version

   

PostgreSQL creates a default database cluster, uses your macOS username as the default role. Local connections may use trust authentication (no password). This is fine for quick testing—but not ideal even for local development.

 

2. Create User

Access PostgreSQL Shell by executing below command.

 

psql postgres

$ psql postgres
psql (14.22 (Homebrew), server 18.3 (Homebrew))
WARNING: psql major version 14, server major version 18.
         Some psql features might not work.
Type "help" for help.

postgres=#

   

Create a User

Execute below command to create user.

 

CREATE USER app_user WITH PASSWORD 'strong_password';

   

Create a Database

 

CREATE DATABASE app_db OWNER app_user;

   

Grant Privileges

 

GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;

   

This ensures your user can:

 

·      Connect

·      Create tables

·      Insert/update/delete data

 

Exit from the Sql Shell

 

\q

   

3. Connect to the Database

 

psql -U app_user -d app_db

   

4. Enable Password Authentication (Important)

By default, macOS installs may allow login without a password.

 

Open another new terminal and edit config file:

nano /opt/homebrew/var/postgresql@14/pg_hba.conf

 

Find following line

 

local   all             all                                     trust

   

Replace it with

 

local   all             all                                     md5

   

5. Restart PostgreSQL

 

brew services restart postgresql

   

6. Test password login

 

psql -U app_user -d app_db -W

   

Create sales_data table by executing following statement.

 

CREATE TABLE sales_data (
    id SERIAL PRIMARY KEY,
    order_date DATE,
    region VARCHAR(50),
    product VARCHAR(100),
    category VARCHAR(50),
    quantity INT,
    price NUMERIC(10,2),
    revenue NUMERIC(10,2)
);

   

Insert sample data.

 

INSERT INTO sales_data (order_date, region, product, category, quantity, price, revenue) VALUES
('2024-01-01', 'India', 'Laptop', 'Electronics', 2, 60000, 120000),
('2024-01-02', 'India', 'Phone', 'Electronics', 5, 20000, 100000),
('2024-01-03', 'US', 'Tablet', 'Electronics', 3, 30000, 90000),
('2024-01-04', 'UK', 'Chair', 'Furniture', 10, 5000, 50000),
('2024-01-05', 'India', 'Desk', 'Furniture', 4, 7000, 28000),
('2024-01-06', 'US', 'Monitor', 'Electronics', 6, 15000, 90000),
('2024-01-07', 'UK', 'Keyboard', 'Accessories', 15, 2000, 30000),
('2024-01-08', 'India', 'Mouse', 'Accessories', 20, 1000, 20000);

   

Verify data

 

app_db=> SELECT * FROM sales_data;
 id | order_date | region | product  |  category   | quantity |  price   |  revenue  
----+------------+--------+----------+-------------+----------+----------+-----------
  1 | 2024-01-01 | India  | Laptop   | Electronics |        2 | 60000.00 | 120000.00
  2 | 2024-01-02 | India  | Phone    | Electronics |        5 | 20000.00 | 100000.00
  3 | 2024-01-03 | US     | Tablet   | Electronics |        3 | 30000.00 |  90000.00
  4 | 2024-01-04 | UK     | Chair    | Furniture   |       10 |  5000.00 |  50000.00
  5 | 2024-01-05 | India  | Desk     | Furniture   |        4 |  7000.00 |  28000.00
  6 | 2024-01-06 | US     | Monitor  | Electronics |        6 | 15000.00 |  90000.00
  7 | 2024-01-07 | UK     | Keyboard | Accessories |       15 |  2000.00 |  30000.00
  8 | 2024-01-08 | India  | Mouse    | Accessories |       20 |  1000.00 |  20000.00
(8 rows)

  

Previous                                                    Next                                                    Home

Thursday, 3 November 2022

Hibernate 6: Embedded and Embeddable example

In this post, I am going to explain how to map an entity that contain embedded properties to a single database table using Embedded and Embeddable annotation.

 

For example, I have a contact table with below ddl.

create table contact (
    id integer not null,
    age integer,
    firstName varchar(255),
    lastName varchar(255),
    middleName varchar(255),
    primary key (id)
)

 

As you see above ddl, contact has 6 properties. There are two ways to define the entity class.

a.   Mention all the six properties in Contact class (or)

b.   You can define a Name class with properties and firstName, lastName, middleName and embed the Name variable in Contact class.

Since first approach is straight forward, let’s try the second one.

 

Step 1: Define Name class and mark it as embeddable. @Embeddable annotation tells that this class is embeddable by other entities.

 

@Embeddable
public class Name {

    private String firstName;

    private String middleName;

    private String lastName;

    ...........
    ...........
}

Step 2: Define Contact entity.

@Entity
@Table(name = "contact")
public class Contact {

    @Id
    private Integer id;

    @Embedded
    private Name name;

    private Integer age;

    ...........
    ...........
}

As you see the Contact class definition, I embedded the Name variable using @Embedded annotation.

 

As a result, we have our entity Contact, embedding name details and mapping to a single database table.

 

Find the below working application.

 

Step 1: Create new maven project 'hibernate-embeddable-embedded-demo'.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hibernate-embeddable-embedded-demo</artifactId>
    <version>1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <java.version>15</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

    </properties>

    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.4.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.1.2.Final</version>
        </dependency>

        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
            <version>2.2</version>
        </dependency>


    </dependencies>
</project>

Step 3: Create hibernate.cfg.xml file under src/main/resources folder.

 

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

    <session-factory>

        <!-- Database Connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://127.0.0.1:5432/test</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>

        <!-- Enable the logging of all the generated SQL statements to the console -->
        <property name="show_sql">true</property>

        <!-- Format the generated SQL statement to make it more readable, -->
        <property name="format_sql">true</property>

        <!-- Hibernate will put comments inside all generated SQL statements to 
            hint what’s the generated SQL trying to do -->
        <property name="use_sql_comments">false</property>

        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>

        <!-- mappings for annotated classes -->
        <mapping class="com.sample.app.entity.Contact" />

    </session-factory>

</hibernate-configuration>

Step 4: Define Name and Contact classes.

 

Name.java

package com.sample.app.entity;

import jakarta.persistence.Embeddable;

@Embeddable
public class Name {

    private String firstName;

    private String middleName;

    private String lastName;
    
    public Name() {}

    public Name(String firstName, String middleName, String lastName) {
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

Contact.java

package com.sample.app.entity;

import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "contact")
public class Contact {

    @Id
    private Integer id;

    @Embedded
    private Name name;

    private Integer age;

    public Contact(Integer id, Name name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

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

    public Name getName() {
        return name;
    }

    public void setName(Name name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

Step 5: Define HelloWorld application class.

 

HelloWorld.java

package com.sample.app;

import java.io.IOException;
import java.net.URISyntaxException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import com.sample.app.entity.Contact;
import com.sample.app.entity.Name;

public class HelloWorld {
    private static final SessionFactory SESSION_FACTORY = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {

            final StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                    .configure("hibernate.cfg.xml").build();

            final Metadata metaData = new MetadataSources(standardRegistry).getMetadataBuilder().build();

            return metaData.getSessionFactoryBuilder().build();

        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }

    }

    public static void main(final String args[]) throws ClassNotFoundException, IOException, URISyntaxException {
        final Contact contact1 = new Contact(1, new Name("Krishna", null, "G"), 34);
        final Contact contact2 = new Contact(2, new Name("Ram", "krishna", "Geeta"), 39);

        try (final Session session = SESSION_FACTORY.openSession()) {
            session.beginTransaction();
            session.persist(contact1);
            session.persist(contact2);
            session.getTransaction().commit();
        }

    }
}

Total project structure looks like below.




Run HelloWorld.java class, you will see below messages in the console.

Aug 08, 2022 8:30:46 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 6.1.2.Final
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: Loaded JDBC driver class: org.postgresql.Driver
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001012: Connecting with JDBC URL [jdbc:postgresql://127.0.0.1:5432/test]
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {password=****, user=postgres}
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Aug 08, 2022 8:30:46 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH10001115: Connection pool size: 20 (min=1)
Aug 08, 2022 8:30:47 PM org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl logSelectedDialect
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
Aug 08, 2022 8:30:47 PM org.hibernate.metamodel.internal.EntityInstantiatorPojoStandard resolveConstructor
INFO: HHH000182: No default (no-argument) constructor for class: com.sample.app.entity.Contact (class must be instantiated by Interceptor)
Hibernate: 
    
    drop table if exists contact cascade
Aug 08, 2022 8:30:47 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@95eb320] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: 
    
    create table contact (
       id integer not null,
        age integer,
        firstName varchar(255),
        lastName varchar(255),
        middleName varchar(255),
        primary key (id)
    )
Aug 08, 2022 8:30:47 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@4fe64d23] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Aug 08, 2022 8:30:47 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: 
    insert 
    into
        contact
        (age, firstName, lastName, middleName, id) 
    values
        (?, ?, ?, ?, ?)
Hibernate: 
    insert 
    into
        contact
        (age, firstName, lastName, middleName, id) 
    values
        (?, ?, ?, ?, ?)

You can confirm the same by querying postgres.

test=# \d+ contact;
                                                   Table "public.contact"
   Column   |          Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
------------+------------------------+-----------+----------+---------+----------+-------------+--------------+-------------
 id         | integer                |           | not null |         | plain    |             |              | 
 age        | integer                |           |          |         | plain    |             |              | 
 firstname  | character varying(255) |           |          |         | extended |             |              | 
 lastname   | character varying(255) |           |          |         | extended |             |              | 
 middlename | character varying(255) |           |          |         | extended |             |              | 
Indexes:
    "contact_pkey" PRIMARY KEY, btree (id)
Access method: heap

test=# 
test=# SELECT * FROM contact;
 id | age | firstname | lastname | middlename 
----+-----+-----------+----------+------------
  1 |  34 | Krishna   | G        | 
  2 |  39 | Ram       | Geeta    | krishna
(2 rows)

You can download the complete working application from this link.

 

Previous                                                    Next                                                    Home