Skip to main content

How I get started!

Starting simple

So, putting the cards on the table: I have a hard time getting started with… well, everything. I have always had that issue. But that’s not what I’m really going to talk about today… or write about, he he, I’ll have to get used to this blogging thing.

What I do want to write about today is how I get started, and this is something my dear wife has taught me over time:

Start with something simple.

This sounds obvious, almost trivial, but in practice, it is incredibly hard when you are building software and constantly thinking ahead.

To help myself get unstick, I decided to follow four very simple steps, which I’ll walk through there.

1. Write one sentence

Before writing any code, drawing diagrams, or thinking about architecture, I forced myself to write one single sentence, describing what I wanted to achieve.

And the sentence I wrote:

I want to be able to save a user/member in a database and fetch it again.

With that sentence, I knew what was needed, a user entity and a database, easy! Now to what that entity requires, so on to step two.

2. What is the least that needs to exist?

Here, I try to answer three simple questions in my sentence:

What thing am I saving?
a user
What does it HAS to have?
id,email
Where is it saved?
a database (JPA)

Awesome, super simple, almost boring, I know. But for some people, this is the way to go!

3. Make it boring!

This is almost the most understimated step, but making it so simple its boring is how most people can better get through. If you keep it at:

  • One entity
  • One table
  • One repository/DAO

If this feels like its too simple, thats a good sign! Keep going. The goal here is not to impress anyone, this is for you to get started!

4. Only expand after something works

Only after I could:

  • Persist a user
  • Retrieve it again
  • See an ID printed in the console (that matched)

then I allowed myself to think about what comes next.

This mindset shift alone helped me move forward instead of getting stuck to planning a system that didnt exist yet.

First domain model

The first entity I implemented was User, containing only essential fields:

  • id
  • email
  • firstname
  • lastname
  • role (as enum)
  • passwordHash (placeholder for later security work)

I also made a few conscous early decisions:

  • Database constraints (nullable, unique)
  • Enums instead of strings
  • Letting the database help enforce rules

This keeps business rules close to the data model and avoids unnecessary complexity later.

Introducing Company and relationships

Once the basic User persistence worked, I introduced a Company entity.

A user must belong to a company in order for a membership to make sense later, so instead of storing a raw companyId, I modeled this as a JPA Many-to-One relationship.

This reflects the real-world domain better and allows Hibernate to manage:

  • Foreign keys
  • Joins
  • Object navigation

Core domain - Week 1

Core Domain - Week 1Core Domain - Week 1Userid : Longemail : Stringfirstname : Stringlastname : StringpasswordHash : Stringrole : RoleCompanyid : Longname : StringRoleMEMBERCOMPANY_ADMINSYSTEM_ADMINbelongs tomanyone

Persistence layer - DAO responsibility

For pesistence, I implemented a DAO for each entity.

The DAO’s responsibility is only:

  • Opening an EntityManager
  • Handling transactions
  • Persisting and retrieving entities

It contains no business logic, no validation and no application rules.

This separation keeps the code easier to reason about and easier to extend later.

DAO interaction overview

DAO InteractionDAO InteractionMainCompanyDAOUserDAOEntityManagerDatabaseMainMainCompanyDAOCompanyDAOUserDAOUserDAOEntityManagerEntityManagerDatabaseDatabasecreateCompany()createUser()

Understanding entity state

One of the most important things I learned this week was how entity state works in JPA.

When a Company is persisted in one transaction and later used when creating a User, the entity becomes detached..
Hibernate idtentifies entities only by their primary key, so calling merge(company) ensures the entity is reattached to the current persistence context before persisting the User.

This was a key “aha” moment for me, that clarified how Hibernate knows which database row an object represents.

Querying data - finding a user by email

Since EntityManager.find() only works with primary keys, I used JPQL to find users by email:

    SELECT u FROM User u WHERE u.email = :email

The DAO then returns an Optional<User>, making the absence of data explicit and avoiding null

Example usage:

    userDAO.findByEmail("mail@mail.dk")
        .ifPresentOrElse(
            userFound -> System.out.println(
                "Found: " + userFound.getEmail() + " id=" + userFound.getId()
            ),
            () -> System.out.println("No user found")
        );

Reflection

This session taught me that:

  • Getting started is often harder than solving the problem istelf
  • Over-planning can block progress
  • A small, working foundation beats a large unfinished design
  • JPA concepts make much more sense once you see them fail and then work

Most importantly, I now have a *stable base I can confidently build on in the coming weeks.

My next steps

  • Add more read operations (findById,findAll, etc.. ALL THE CRUDS!)
  • Introduce a service layer when business rules appear
  • Prepare for REST endpoints
  • Continue expanding the system incrementally

Until next time! See you around!