I am brand new to the concept of embedded databases and have chosen HSQLDB to be the embedded DB for my Java app. I think I am fundamentally not understanding something: nowhere do I see how/where to:
Define username/password credentials that must be used for connecting to a database
Creating a new database (e..g, db_myapp)
Creating tables for that new database
With a non-embedded ("normal") DB, I would first use a DB client to connect to the database, and CREATE the db_myapp DB as well as any tables it should have. My app would then expect those tables to exist at runtime.
But with HSQLDB, I have no such DB server to connect to, so I don't see how/where I can create these databases/tables/credentials ahead of time, before my app runs.
And maybe that's exactly what an "embedded" DB does; perhaps its an entire DB embedded inside a JDBC driver? In any event, I still need a way to accomplish the 3 things listed above.
The only thing I can think of is to run some initialization code every time that my app starts up. This code would check for the existence of these constructs, and if they don't exist, then it would create them.
There are several problems here:
This approach might work with databases and tables, but not the credentials I need on the JDBC Connection itself. How/where do I create those?
I'm not even sure if this is the right/normal approach to using an embedded HSQLDB; can someone confirm I'm on track (that is, the "check-to-see-if-it-exists-and-if-not-then-create" approach)?
What happens if I accidentally execute code that tries creating a new database/table eve when it already exists? Will HSQLDB just ignore it or will it blow out my existing DB/tables?
The short answer is that you're pretty much on the right track.
Connecting to the embedded database is really no different from connecting to a normal db server, except that the connection string is a bit different. This section has information on that. The thing is that you don't really have separate 'databases' to choose from, it's just specified in the connection string. For the connection:
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");
This will give you a connection to an embedded database engine that persists the data in the file at /opt/db/testdb. The default username for an embedded database will always be 'SA' with no password. I honestly don't know if it'll work, but if you really need to set a different password, you can try executing ALTER USER SA SET PASSWORD <newPassword>. It'll probably work...
As far as creating tables and such, there's a couple of way of going about this, depending on whether the database will be persisted as a File or in memory. Often times, embedded dbs get used for pretty simple data, and so the tables get created by executing a statement right after initializing the connection. CREATE TABLE IF NOT EXISTS ... is the usual way of doing things. This allows you to create a table only if it doesn't already exist.
If you're working with a file-base database, then hsqldb gives you another option. Take a look at this documentation about accessing a database using their tools. This would allow you to create a file-base database ahead of time, and set things like username/password and setup all your tables. Then you can just copy over the resultant file to be used by your application. Then everything would be setup before your application connects to it.
So ultimately, you have the option to go either way. You can either have your application set everything up when the connection is initialized, or you can set it up manually ahead of time. My preference is to have the application set it up in code simply because then your table definitions are kept closer to the code that actually uses them. I haven't used an embedded database like that for really complex data, though, so I can't honestly say how well that scales.
Related
I'm building an application using Java and Spring Boot where I want to query two foreign databases (they might have different schemas and data) every time I run. Therefore I'd like to query two different databases every time. After accessing those databases, I would then like to store the result (my business logic) on a local static database.
I originally wanted to store all the database data (user, pass, url) in the application.properties, but then realized that this might not be best practice as the details for the two DBs I'm querying will be received as input from the user. Therefore, I'm not sure if it's the best idea to update and overwrite application.properties every time I receive a new request (please let me know if there's a better way to do this.
Assuming I have the DBs info in application.properties, I've followed multiple tutorials for multiple DB connections in Spring, and they all followed something along the lines of making configuration files for each DB, calling a repository/DAO file for each DB, which references a model of said DB. That seems a bit problematic for me as I don't know the schema of the databases before hand, so I can't define a model class. And even if I did, this will probably change across databases, so I'm really not sure what to do.
Is there a more flexible/versatile way to query "foreign" databases with Spring or old school Java given that I don't know what their schemas might look like?
Any help is greatly appreciated!
Multiple databases config have to be maintained in application.properties or config class as a best practice. Refer here - https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources
You can have a POJO with DB properties which gets assigned from user provided values. Use that POJO in a DB config class to connect to different databases.
Not knowing schema is not a problem as you can handle data with java collections.
I know there are similar questions but I want to ask for advice for my particular case. I have a web application that use jdbc. This application, at startup, is creating a Map of connections. When a db change need to be done a connection from this map(there are multiple connection for more db's and reading and writing are done on the same db for every one of them) is send in DAO class using the constructor of that class and using that connection the query is executed.
The thing is that now a change need to be done: reading and writing will be done on two different db's and the code need to be changed in order for this to work. I need to know what is the best approach to make the change.
I'm still rather new to java and I think I've started a project with a problem.
I created a job for a friend in which there are employees, shifts, sites and these needed to be loaded at the beginning.
I went looking for solutions and decided to use a Derby database. I've now programmed the Application and it works fine with the database. It loads all parameters and creates objects for handling,
Now I need to deploy my project to my friends computer so he can use it and I think I have the database set up wrong. I think I needed it to be embedded? so it goes with the application.
So my questions are what are my choices,
I read I can change the database to an 'embedded' one by making the database a class? I have no idea how to do this and maybe because I'm new to java, I'm finding all the write ups on this subject difficult to understand.
Alternatively I thought maybe I can install Derby separately and connect to that?
Or maybe I can drop the Derby idea and switch entirely to another database entirely,
I'm a bit confused over my choices here, basically I've built an application around an installation of Derby DB using this line to connect to it.
jdbc:derby://localhost:1527/SG_database
If someone can give me some 'Plain English' options here I would very much appreciate it.
To reconfigure your application to use Derby as an embedded database, all you have to do is change that JDBC Connection URL to jdbc:derby:SG_database, and change your CLASSPATH so that your program references derby.jar rather than derbyclient.jar. You should possibly add ;create=true to the end of that URL so that, the first time your friend runs your application, the database is created on their machine.
But yes, you have other choices, and without knowing a fair amount about your application it's hard to give you very detailed guidance.
When your friend is using the application, do you want you and your friend to be sharing the same set of data? Or is your application designed so that your data and your friend's data have nothing in common?
If you want to be sharing the data, then yes it will be important to have a single instance of the database, and both of you have to share it, in which case a client-server configuration can work quite well.
If you want to be two completely separate applications, with nothing shared, and each of you has your own copy of the data, then an embedded configuration can work quite well.
Perhaps you could simply try the embedded configuration, see how it behaves with your application, and then return here if you have a more specific question to ask?
I couldn't find an answer to this question. How can I export a Java project that makes use of a PostgreSQL database?
I want to use the same database on another computer. Do I need to export the database itself with the project? How can this be done?
What should the connection URL be, so that the database is accessible on another computer?
I'm using JDBC, and I'm on Windows.
Thanks in advance.
EDIT: Wouldn't I also need to dynamically retrieve the username and password on the other computer, instead of using the specific username and password I have on my computer in PostgreSQL?
It really depends on what you want to achieve.
Shared database between hosts
Do you want the application on both computers to use the same database, so that changes made by one are seen on the other? If so, you need to configure each copy of the application to connect to the same database instance on one of the machines. This is usually done by changing the JDBC URL. You'll need to configure PostgreSQL on the machine that'll be the database server so it allows connections from the other hosts, ensure they can talk to each other over TCP/IP, etc.
Fresh DB on each host
Do you want each install to have a separate instance of the database, so changes made on one have no effect on the other, and where each instance starts out with a blank, empty database (or one with only static contents like lookup tables)? If so, you should generally define the database using SQL scripts, then have the application run the SQL scripts when first installed on a machine. If you've defined the database by hand so far, you can use pg_dump to create a SQL script that you can use as the basis for this, but I really advise you to look into tools like Liquibase for schema management instead.
"Fork" current state
Do you want each instance of the application on a machine to have an independent database, so changes made on one have no effect on other instances on other machines, but where the starting state of an install is what was in the database on the other host? If so, you need to dump and reload the database alongside the application, using pg_dump -Fc and pg_restore. You can automate this within your application / build system using tools like ProcessBuilder, or do it manually.
There's no generic, canned way to do this. It'll require you to define an application deployment procedure, maybe produce an installer, etc.
Is it possible to use Hibernate and connect to a database with a read only connection? I will be working on a project that will require connecting to an existing database, pulling data from it, and doing some complex data manipulation in the application. Throughout all of this I can`t change anything in the database, hence the read only connection requirement.
My first thought was to pull the data from the database using Hibernate so that I can have ready made Java objects represent the data, however, I can`t seem to find any information on how to force Hibernate to use a read only database connection ... I have a feeling this might actually be impossible, but I want to find out from others before I pursue other ideas.
I don't have enough reputation to comment, apparently :(
But responding to your comment about the cases where Hibernate may still write back to the DB, you could manually detach the object from your persistence context, after which Hibernate would cease caring about the state of the object & whether its been modified.
You can use: Session.setDefaultReadOnly( true );
http://docs.jboss.org/hibernate/orm/3.5/reference/en-US/html/readonly.html#readonly-api-loaddefault
To be bullet-proof safe against anything you do in the application, you need to assign read-only permissions to the DB user that Hibernate is configured to use. This has to be done on the database side. Otherwise, if you rely only on the configuration on the application side, you can always make a mistake (forget to detach the entities, forget to set the session to read-only mode etc.).