Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Wierd exception when trying to use Oracle.DataAccess

Discussion in 'Scripting' started by Hoshiqua, May 25, 2017.

  1. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    Hello !

    I am trying to use an Oracle database for a game I'm working on, as such I installed the necessary tools outside Unity, namely Oracle database and Oracle client.

    I then put the DLLs I needed into the Unity project and now when using Oracle.dataaccess I get no compile errors.

    Problem is, when I try to create an OracleConnection object, I get this exception :

    System.TypeInitializationException: An exception was thrown by the type initializer for Oracle.DataAccess.Client.OracleConnection ---> System.TypeInitializationException: An exception was thrown by the type initializer for Oracle.DataAccess.Client.CThreadPool ---> System.InvalidCastException: Cannot cast from source type to destination type.
    at Oracle.DataAccess.Client.CThreadPool..cctor () [0x00000] in <filename unknown>:0
    --- End of inner exception stack trace ---
    at Oracle.DataAccess.Client.OracleInit.Initialize () [0x00000] in <filename unknown>:0
    at Oracle.DataAccess.Client.OracleConnection..cctor () [0x00000] in <filename unknown>:0
    --- End of inner exception stack trace ---
    at DBConnection.Open () [0x0006e] in C:\Users\march\Documents\UnityProjects\SwordAndPlough\Assets\Sources\Database\DBConnection.cs:38
    UnityEngine.Debug:LogError(Object)
    DBConnection:Open() (at Assets/Sources/Database/DBConnection.cs:44)
    Game:Start() (at Assets/Sources/Game/Game.cs:10)

    I have tryed reinstalling Oracle database and client many times, tryed taking a look at machine.config... I ran out of solutions other than yanking on my hair and crying in a corner.

    I did notice that most of the similar posts I found on the internet did not involved the <filename unknown> part, so maybe the solution is simpler than I thought. Regardless, I need help !
     
    Last edited: May 26, 2017
  2. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    I think it would be a good idea to provide the code in DBConnection.cs
     
  3. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    BTW, just a random idea, you might want to test your Oracle connection outside of Unity to make sure the database is up and running fine. Examples... use TNSPING utility to ping the database.. or grab something like TOAD or SQL developer or something to open a connection to the database.

    The error does look to me like it's unrelated (at least at this point) to your DB being installed properly or not.. seems like something not correctly coded in your script.. maybe your connection string is built wrong, or something else. Hard to say, but if you share that with us, it might help narrow it down.
     
  4. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    The DB is up and running, I could connect to it with SQL developer.

    Here's the code : Very sorry, it's evident you guys would want to see it.

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using Oracle.DataAccess.Client;
    6. using Oracle.DataAccess.Types;
    7.  
    8. public static class DBConnection
    9. {
    10.  
    11.     //
    12.     static string Host;
    13.     static int Port;
    14.     static string SID;
    15.     static string Username;
    16.     static string Password;
    17.     //
    18.  
    19.     static bool Initialized = false;
    20.     public static void Initialize(string host, int port, string sid, string username, string password)
    21.     {
    22.         if (Initialized) throw new Exception("DBConnection was already initialized !");
    23.  
    24.         Host = host;
    25.         Port = port;
    26.         SID = sid;
    27.         Username = username;
    28.         Password = password;
    29.     }
    30.  
    31.     static OracleConnection Connection;
    32.     public static void Open()
    33.     {
    34.         try
    35.         {
    36.             string connString = "user id="+Username+";password="+Password+";data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=+"+Host+")(Port="+1521+"))(CONNECT_DATA=(SERVICE_NAME="+SID+"))";
    37.  
    38.             Connection = new OracleConnection();
    39.             Connection.ConnectionString = connString;
    40.  
    41.             Connection.Open();
    42.         } catch (Exception e)
    43.         {
    44.             Debug.LogError(e.ToString());
    45.         }
    46.     }
    47.  
    48.  
    49. }
     
    Last edited: May 26, 2017
  5. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    One request... Use code tags when pasting code.. it formats it nicely.

    Just eyeballing your code though, why is there a + symbol right after HOST in your setting of connString? I don't think that one should be there.
     
  6. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    Thanks for spotting it, indeed it had nothing to do there. However it did not fix the error :( How do you use code tags ? I tried to put a <code> tag around it but didn't do anything in preview.
     
  7. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Ahh, too bad that didn't fix it.

    But for code tags, you can actually use the button labelled insert (three to the right of the smilee face button) then pick code, or just use hard brackets, not the < you used... i.e.:

    Code (csharp):
    1.  
    2.  [ c o d e]
    3.  
    If you could also point out which line in the script is line 41, that might help. It looks like it's erroring on "Connection = new OracleConnection();" , but I'm not sure. If it's failing there, I wonder if you're missing a reference / dll or something. But let's start by finding out what line it's erroring on.
     
  8. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    Done. Also updated the error in the first post, a few line numbers changed for some reason.
     
  9. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Also, one article you might find helpful:
    http://answers.unity3d.com/questions/142275/how-do-i-connect-to-an-oracle-database.html

    I believe this guy had troubles using Oracle.DataAccess to connect to Oracle, and I saw someone else having similar issues. This fellow ended up using ODBC to connect, which he notes has some limitations, but it may work for you. At the very least, it will let you do a quick test to see if you can connect that way, and then you can continue troubleshooting the with Oracle.DataAccess, if you really need to connect that way.

    It does look like it's erroring on Connection = new OracleConnection(); though, which again makes me feel like we can eliminate any issues with your database, or even your connection string, because at this stage you're not even making any reference to your actual DB yet, just trying to create an empty Connection object. So I'm still wondering if there's some other libraries needed or something like that.

    Again, try the method described in the article I linked first, just to see if you can connect that way. If so, that might be all you need. If that's not good enough, but it works, well, at least we know that you can connect to Oracle from Unity, so that helps eliminate potential problems.
     
  10. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    What is the actual type of Exception? If it is an OracleException, you can inspect the Code property for potentially a little more information.

    Also, I noticed the documentation uses the OracleConnection(string connectionString) overload instead of the OracleConnection() constructor, even in the example for the default constructor. Maybe try changing your code to match:

    Code (csharp):
    1. string connString = "user id="+Username+";password="+Password+";data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=+"+Host+")(Port="+1521+"))(CONNECT_DATA=(SERVICE_NAME="+SID+"))";
    2. using (Connection = new OracleConnection(connString))
    3. {
    4.   // ...
    5. }
    p.s. If you've never heard of sql injection attacks, make sure to give it a quick look up before continuing.
     
  11. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Hoshiqua, just for the record, I answered your question because I work with Oracle databases for a living... but I unfortunately have never made a DB connection from Unity. Trying to help out as best as I can, but hopefully some others that have made a DB connection in Unity have some info here for you.
     
  12. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    InvalidCastException: Cannot cast from source type to destination type.
    Oracle.DataAccess.Client.CThreadPool..cctor ()
    Rethrow as TypeInitializationException: An exception was thrown by the type initializer for Oracle.DataAccess.Client.CThreadPool
    Oracle.DataAccess.Client.OracleInit.Initialize ()
    Oracle.DataAccess.Client.OracleConnection..cctor ()
    Rethrow as TypeInitializationException: An exception was thrown by the type initializer for Oracle.DataAccess.Client.OracleConnection
    DBConnection.Open () (at Assets/Sources/Database/DBConnection.cs:38)
    Game.Start () (at Assets/Sources/Game/Game.cs:10)

    That's what the console shows when I catch OracleException and logs its ErrorCode. Doesn't tell us much more..

    I might try the other way but I would like to make this one work just to be sure I've got access to anything I could need. First time I'm working with databases.

    For DLLs I have Oracle.DataAccess and System.Data. I got the Oracle.DataAccess dll from the ODAC bin folder I installed previously and I got the System.Data from the files of some other game. Actually now that I remember that, couldn't System.Data be the culprit ? I don't see any reason why it wouldn't work but maybe I got it from the wrong source... Could it cause such an error ?
     
  13. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    That doesn't look like an error code, it looks like a stack trace. Just to be clear, I was wondering what this code would log:
    Code (csharp):
    1. try
    2. {
    3.   string connString = "user id="+Username+";password="+Password+";data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=+"+Host+")(Port="+1521+"))(CONNECT_DATA=(SERVICE_NAME="+SID+"))";
    4.   using (Connection = new OracleConnection(connString))
    5.   {
    6.     // ...
    7.   }
    8. }
    9. catch (OracleException e)
    10. {
    11.   Debug.LogError(e.Code);
    12. }
    The exception is an invalid cast and appears to originate in Oracle.DataAccess.Client.CThreadPool..cctor (). I consider that pretty low level and not really something you have control over with code. My guess is that there is some incompatibility in the assemblies you are using. Maybe the incompatibility is with mono or maybe just the assemblies you copied. Unfortunately, this will be a tough one to crack.
     
  14. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    The Oracle documentation here does give an example like how he's doing here:
    https://docs.oracle.com/cd/B28359_01/win.111/b28375/OracleConnectionClass.htm#i1000099

    I do think though too that it's not an issue with his database, and probably not an issue with syntax here, but either the wrong libraries used, or a compatibility issue like you suggested. There doesn't seem to be a lot of info out there for connecting Unity to Oracle.. I assume most are going to use MySQL for their database. Might need to get in touch with either Unity developers or Oracle to help with this one. Outside of that, again, try with ODBC, although that might not be desireable :(
     
  15. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    It logs the exact same thing unfortunately.

    I don't really have a clue... This is wierd. One last lead is that, from what I understand, you need a machine.config file to tell where the libraries are or something like that. When I went to look at the Microsoft.NET/Framework folder, I noticed there was a config folder with a machine.config file inside it for 4.0.30319 but not for 3.5. Could this be the cause ? I did see on similar threads that this problem can be caused by the Oracle DLL not finding some files.
     
  16. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    UP, I still have this problem and didn't find any solutions :( Has no one else ever been in this mess ? :p
     
  17. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    UP. Is that a problem I can't be helped with ? Anyone know some place I could go ask for more specialised help ?
     
  18. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Like I said in my post, I think your best bet would be to talk to the Unity devs (i.e. a support ticket or something) or Oracle. Not sure Oracle can really help though, and their support can be tough to work with. You'll be hard pressed to find hobbyists that have an Oracle database in their projects. Oracle is easily my favorite database, but it's more enterprise. So I'm just saying it might be a little hard to find help here or at least a lot more patience as the people that will have used it from unity are quite limited I'm sure.
     
  19. Hoshiqua

    Hoshiqua

    Joined:
    Jul 22, 2016
    Posts:
    77
    You're right. Unity it is. Sent a report through the editor's bug reporting. If I get an answer I'll make sure to post it here for people in the future searching a solution for the same problem.
     
    cstooch likes this.
  20. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    That's good, I'd really like to know too what it is.. a bug or some process or syntax thing.