db already exists with different case other - java

i try to read data from a MongoDB. and i have a problem:
Exception in thread "main" com.mongodb.MongoException: db already exists with different case other
the exeption throws from here:
DBCursor cur[] = new DBCursor[cursorSize];
...
cur[i].hasNext() // Exeption
what is the problem?
the version of Mongo is 2.10.1

This error indicates that you are trying to create a database that differs by case only from a database name that already exists. For example, if you already have a database called "test", you will get this error trying to create "Test", "TEST", or other variations of upper or lower case for the existing name.
The database name is used in naming the data extent files, so clashes in name could cause Bad Things to happen on case-insensitive file systems.
The MongoDB manual has further details on Naming Restrictions, including case sensitivity and restrictions specific to different operating systems.
The useful part of the error message appears to have been omitted in the question description, but what you should see as part of this message is the name of the existing database as well as the new name that is being rejected.
The corresponding MongoDB 2.4 server code snippet is:
ss << "db already exists with different case other: [" << duplicate << "] me [" << _name << "]";

I think Stennie has very well defined and explained why you might be getting this error. However, in my case, I encountered an interesting case which you or others may also encounter. I had the the database called "HDB" but when I added my user to system.users collection with "db":"hdb" (lower case). So, I spent an hour or so trying to see what could have gone wrong while I was able to login. So, if you get this error make sure you did not accidentally add your user with lower/different case for db name. To confirm this.
1.Log in as the admin/default account run
db.system.users.find().pretty();
and then look for the user name that is getting this error along with the "db" in that json object and compare it against actual database you have.
Run
show dbs;
compare the db you see in step one against the name of db that you see in this step. (the command will show you all the databses you have but clearly you should only be concerned with the ones that you use/see in step one).

Related

MYSQL/JDBC Forming a JDBC connection URL to connect to a database having a question mark(?) in its name?

I have a database with a name order?id(don't ask me why). The connection url I formed is
jdbc:mysql://localhost:3306/order?id
which seems to be invalid as it throws an error
Unknown database "order"
It is because ? is treated as a separator(or some character having special significance, I really don't know).
So after doing some research, I found that the URL can be percent encoded, replacing ? in database name with %3F like
jdbc:mysql://localhost:3306/order%3Fid
Which still fails as the DB is trying to look for the databaseorder%3Fid and not order?id. So it cannot find the database and throws an error.
Also tried replacing ? with ?? as suggested by some websites. Still doesn't work. How do we specify such db names?
Edit
Tried adding single quote in the database name as
jdbc:mysql://localhost:3306/'order?id'
Still no luck.

Differentiate 'Could not allocate space for object' Exception

I am getting
com.microsoft.sqlserver.jdbc.SQLServerException: Could not allocate space for object
as filegroup is full.
I want a way to identify this SQL exception from other SQL Exceptions.
If I check java.sql.SQLException.venderCode == 1105 will that be enough?And is there any place I can get the description of the 1105 code?
If I check java.sql.SQLException.venderCode == 1105 will that be enough?
Yes, that vendor code (available by calling getErrorCode()) will always map to that error. Just bear in mind it's specific to SQL Server rather than consistent across all SQL implementations.
Various sites like this one detail all the error codes available for SQL server (including 1105.)
Checking the error code alone is sufficient for your need. The returned vendorCode is the SQL Server error number. SQL Server errors and the tokenized message text can be retrieved by the sys.messages DMV. Example for the US English language:
SELECT *
FROM sys.messages
WHERE
message_id = 1105
AND language_id = 1033;

Flyway partial migration of legacy application

In an application with a custom database migrator which we want to replace with Flyway.
These migrations are split into some categories like "account" for user management and "catalog" for the product catalog.
Files are named $category.migration.$version.sql. Here, $category is one of the above categories and $version is an integer version starting from 0.
e.g. account.migration.23.sql
Although one could argue that each category should be a separate database, in fact it isn't and a major refactoring would be required to change that.
Also I could use one schema per category, but again this would require rewriting all SQL queries.
So I did the following:
Move $category.migration.$version.sql to /sql/$category/V$version__$category.sql (e.g. account.migration.1.sql becomes /sql/account/V1_account.sql)
Use a metadata table per category
set the baseline version to zero
In code that would be
String[] _categories = new String[] { "catalog", "account" };
for (String _category : _categories) {
Flyway _flyway = new Flyway();
_flyway.setDataSource(databaseUrl.getUrl(), databaseUrl.getUser(), databaseUrl.getPassword());
_flyway.setBaselineVersion(MigrationVersion.fromVersion("0"));
_flyway.setLocations("classpath:/sql/" + applicationName);
_flyway.setTarget(MigrationVersion.fromVersion(_version + ""));
_flyway.setTable(category + "_schema_version");
_flyway.setBaselineOnMigrate(true); // (1)
_flyway.migrate();
}
So there would be the metadata tables catalog_schema_version and account_schema_version.
Now the issue is as follows:
Starting with an empty database I would like to apply all pre-existing migrations per category, as done above.
If I remove _flyway.setBaselineOnMigrate(true); (1), then the catalog migration (the first one) succeeds, but it would complain for account that the schema public is not empty.
Likewise setting _flyway.setBaselineOnMigrate(true); causes the following behavior:
The migration of "catalog" succeeds but V0_account.sql is ignored and Flyway starts with V1_account.sql, maybe because it somehow still thinks the database was already baselined?
Does anyone have a a suggestion for resolving the problem?
Your easiest solution is to keep the schema_version tables in another schema each. I've answered a very similar question here.
Regarding your observation on baseline, those are expected traits. The migration of account starts at v1 because with the combination of baseline=0, baselineOnMigrate=true and a non empty target schema (because catalog has populated it) Flyway has determined this is a pre-existing database that is equal to the baseline - thus start at v1.

Check if there is an error in update/insert | MongoDB Java driver

I want to check if an insert fails (due to unique=True index in the collection). If there is an error do something. Bellow is an example of my code.
DBCollection user...;
BasicDBObject Doc = new BasicDBObject(... );
String user_exists = user.insert(Doc).getError(); //insert the doc get error if any
if(user_exists!=null){ //any errors?
user.update(new BasicDBObject(...)); // error exists so do smthng
}
The above as it is does not work. I believe that the String user_exists is always null. How can I make the above work?
I have seen similar SO questions and mention the WriteConcern which can be passed in the insert(). E.g.
coll.insert(dbObj, WriteConcern.SAFE);
sources: SO question
or
Mongo docs
However I do not know which one field should I pass (SAFE, ACKNOWLEDGED, UNACKNOWLEDGED etc..) in order to get the error. Maybe I'm pointed in the wrong direction.
I do not wish to raise an exception just to check if there is an error returned by the insert operation.
If you are using WriteConcern.ACKNOWLEDGED (which I think is also SAFE) you don't need to pollute your code with error checking.
For ACKNOWLEDGED, the driver will automatically issue a getLastError command automatically and raise an exception if anything got wrong, for example duplicate index violation.
Starting from v2.10 of the Java Driver, the default Write Concern is ACKNOWLEDGED
EDIT
I do not wish to raise an exception just to check if there is an error returned by the insert operation.
You shouldn't do this, but in any case:
The insert method indeed returns WriteResult. If it's getError() is null, everything is OK, otherwise it returns something such as E11000 duplicate key error index:.... For this to work, you will have to use WriteConcern.UNACKNOWLEDGED

Schemacrawler ignore schema that can't be accessed

I am currently using Schemacrawler to gather information about various databases.
The issue I am having is that the user which the application runs under doesn't have access to every database. If I attempt to retrieve the list of schemas:
SchemaCrawlerOptions schemaCrawlerOptions = new SchemaCrawlerOptions();
schemaCrawlerOptions.setSchemaInfoLevel(SchemaInfoLevel.minimum());
schemaCrawlerOptions.setTableTypes(new TableType[] { TableType.table });
Database database = SchemaCrawlerUtility.getDatabase(connection, schemaCrawlerOptions);
database.getSchemas()
... a SchemaCrawlerException is thrown (The server principal "..." is not able to access the database "..." under the current security context.). Is there a way to get only the databases that are accessible (without having to explicitly declare each schema name)?
From the exception you are getting, I am going to assume that you are using SQL Server. You need to set a schema inclusion rule. You can add this to your code snippet above:
schemaCrawlerOptions.setSchemaInclusionRule(new InclusionRule("schema_name.dbo.*", ""));

Categories

Resources