DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Manual Sharding in PostgreSQL: A Step-by-Step Implementation Guide
  • Why Database Migrations Take Months and How to Speed Them Up
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • How Trustworthy Is Big Data?

Trending

  • Understanding IEEE 802.11(Wi-Fi) Encryption and Authentication: Write Your Own Custom Packet Sniffer
  • Designing a Java Connector for Software Integrations
  • Mastering Advanced Aggregations in Spark SQL
  • How to Build Real-Time BI Systems: Architecture, Code, and Best Practices
  1. DZone
  2. Data Engineering
  3. Databases
  4. MicroProfile CustomConfigSource With Database

MicroProfile CustomConfigSource With Database

Let's see how to implement a MicroProfile ConfigSource based on values read from a Database.

By 
Ralph Soika user avatar
Ralph Soika
·
Sep. 09, 19 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
11.0K Views

Join the DZone community and get the full member experience.

Join For Free

Image title

Using MicroProfile, let's see how to deal with configuration properties in an application.

With the MicroProfile-Config API, there is a new and easy way to deal with configuration properties in an application. The MicroProfile-Config API allows you to access config and property values from different sources, like:

  • System.getProperties() (ordinal=400)
  • System.getenv() (ordinal=300)
  • all META-INF/microprofile-config.properties files

Developers can find a good introduction into the MicroProfile Config API here. Of course, developers can also implement your own config source. However, most of the examples are based on reading custom config values from an existing file, like in the example here.

In this article, I will show how you can implement a MicroProfile ConfigSource based on values read from a Database.

You might also enjoy:  MicroProfile: What You Need to Know

How to Access a Database

The following example shows how developers can implement a custom ConfigSource reading values from a JPA Datasource or an EJB Service. At first glance, it looks quite easy to inject an external resource or a service to access custom config values provided by your application:

public class MyConfigSource implements ConfigSource {

    @PersistenceContext(unitName = ".....")
    private EntityManager manager;

    @Override
    public String getValue(String key) {
       .....
    }
    @Override
    public Map<String, String> getProperties() {
       // read data form JPA Entity manager
       ....
    }
}


However, there is a problem with this direct approach. If you try to inject a JPA Entity Manager or just another EJB into your CustomConfigSource, you will note that your values are not available as expected because the entity manager will be null.

The reason is that in MicroProfile-Config, all ConfigSources are treated as POJOs: the injected values will not be available. For example, imagine another CDI bean may expect a config value to be injected during its startup phase. If your custom ConfigSource itself had dependencies on CDI's, you could get into a startup looping issue. So how can we solve this problem?

The solution is — as often in Java Enterprise — quite simple. To make sure your EntityManager is already injected, you can annotate your custom ConfigSource with @Startup and implement a method annotated with @PostConstruct:

@Startup
@Singleton
public class MyConfigSource implements ConfigSource {
    @PersistenceContext(unitName = ".....")
    private EntityManager manager;

    @PostConstruct
    void init() {
        // load your data from teh JPA source or EJB
        ....
    }
   ...
}


Now developers can access your entity manager (or whatever you have injected) in the init() method. Because MicroProfile Config API still treats your config source as a POJO, your class will be constructed twice — first at the beginning of the Config API and second from the CDI implementation on @PostConstruct. So how can we provide the values for both instances?

The solution is quite simple. Because your configSource is a POJO, you can use static member variables to store your values. In this way, each instance of your custom source will see the same values. With the @PostConstruct annotation, we will provide the values in a kind of lazy loading. Take a look at the full example:

@Startup
@Singleton
public class MyConfigSource implements ConfigSource {

    public static final String NAME = "MyConfigSource";
    public static Map<String, String> properties = null; // note to use static here!

    @PersistenceContext(unitName = ".....")
    private EntityManager manager;

    @PostConstruct
    void init() {
        // load your data from teh JPA source or EJB
        ....
        // override the static property map..
        properties.put(....)
    }

    @Override
    public int getOrdinal() {
        return 890;
    }

    @Override
    public String getValue(String key) {
        if (properties != null) {
            return properties.get(key);
        } else {
            return null;
        }
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public Map<String, String> getProperties() {
        return properties;
    }
}


With the static member variable 'properties', you overload the values from the already constructed ConfigSource. So, any instance of our ConfigSource shares the same values. The values are loaded at a later point in time.

For that reason, our configSource will not show values during the startup phase. This means if you have another CDI bean, you cannot access those values during @PostConstruct. But the values will be available at runtime in any case.

With the disadvantage of the lazy loading mechanism, the solution is quite simple and easy to implement. Of course, you can also use a JNDI Lookup to get the data from a data source without the trick of lazy loading.

The solution shown here allows you to access not only data sources but also any kind of CDI. We use this solution in our open source project 'Imixs-Workflow', which is based in its new version on MicroProfile 2.2.

I hope you will get started with your own MicroProfile ConfigSource soon!

Further Reading

Eclipse MicroProfile

Database

Published at DZone with permission of Ralph Soika. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Manual Sharding in PostgreSQL: A Step-by-Step Implementation Guide
  • Why Database Migrations Take Months and How to Speed Them Up
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • How Trustworthy Is Big Data?

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!