Kotlin same map same Object by multiple keys - kotlin

I have a list of objects that looks like:
data class Student(
val id: Int,
val name: String,
val gpa: Long,
val age: Int
)
I wanna have 2 maps:
student.name -> Student
student.id -> Student
But I don't wanna duplicate the maps.
What would be the best way to achieve this?
I've tried to map Student.id->Student.name and use this but wanted to be sure there is no standard solution already exists for that in Kotlin.
Thanks

Honestly, just make two maps. That's what you want anyway - you have two mappings, id to Student and name to Student. You need a map for each.
Those properties just happen to be stored in the Student object - but imagine if they weren't, would you mind having two maps then? One for separateIdentifier1 to Student, and one for separateIdentifier2 to Student? That would be fine, right - it's just what you have to do!
And if you only had one of those embedded properties, like student.id - would you say "I don't want to make a map because that attribute is already stored in the data"? No, you'd still make the map, right? Because you're not storing data, you're creating a fast lookup that's generated from that data. And it's exactly the same principle if you're creating two or more lookups. And you're not duplicating the objects, just adding an entry of object reference to object reference
Really you just want to generate derived maps, where your actual data is the collection of Student objects, and the mappings for id and name are just automatically generated. You need to ensure that when (if) you add or remove a Student, that both mappings get updated, and that those updates happen together, atomically. Handle concurrency if you need to, that kind of thing.
There's nothing like that in the Kotlin standard library, which is more focused on core functional components you can bolt together into more specialised things. I can't see anything similar in Guava either - they have MultiMaps (one key to many values) and Tables (a pair of keys to a single value) but nothing where you have multiple keys that can be used interchangeably. Just roll your own I reckon!

Related

How to fix my m..n relationship in nosql (mongodb)?

At first I'm trying to make a rally (you know cars with drivers...) database. I have two collections: drivers { name, address, sex, ... } and then another one tournaments { name, location, price, ... }
I try to keep it simple. In a tournament there should be drivers (because a tournament without drivers...well its not nice ^^). And there is my problem, in a normal sql database I could select two primary keys (lets say name in drivers and name in tournaments - just to keep it simple, I know name as primary key is not nice). And because its an m..n relationship (is it right?) I would make a 3. Table with the two primary keys. OK that would be easy. But how should I solve this problem in mongodb. I thought something like: tournaments { name, location, price, ... drivers { driver_1, ..., driver_n } } , but im not sure. I'm using Java so I could make some special Classes which one is handling this relationship problem? I don't understand the other mongodb tutorials. Any ideas? Thank you for any help!
There are a few ways to do this:
As #Gianluca describes you can perform this linking manually by adding a driver's _id ObjectId or another identifying property (probably one you have a unique index on) to a "drivers" array in a tournament document. e.g. tournament : { ... drivers : ["6019235867192384", "73510945093", ...]}
Another option specifically built for this referencing is the DBRef specification which provides a more formal method probably more similar to what you're familiar in the SQL world. DBRef is supported by the java driver and allows you to scope your reference to a collection (basically saying where this reference comes from). I wouldn't be surprised if in the future versions of MongoDB cross-collection queries will be supported, although they are not currently.
More information here.
Also if you aren't using a DAO framework I would suggest Morphia which supports DBRef with a nice #Reference annotation.
I solved the problem using the _id field that every document had and is unique.
So in you case you just need to create a collection that has the ObjectId of the torunaments and some ObjectId from the collection drivers. Or you can just put the ObejctId of the driver directly in the torunaments collection. Probably not the best solution, but it work
Gianluca
Add an array field drivers in the trournaments type and put the _ids of the drivers in there.
To add/remove drivers, just update the field. There is no need for an intermediary N:M mapping table unless the array gets really huge.
If it gets huge, the usual solution is to cut the array into several smaller ones and save them in several documents that you can look up quickly by using the id_ of the container (the tournament). Removing and sorting is then a pain, of course.

Storing polymorphic objects in SQL database

[noob warning!] I need to store some data in some tables where it is like the equivalent of an array of pointers to polymorphic objects. E.g. (pseudo C++)
struct MyData { string name; }
struct MyDataA : MyData { int a,b,c; }
struct MyDataB : MyData { string s; }
MyData * data[100];
I don't really know what google search to enter! How would you store info like this in an SQL database?
My random thoughts:
I could have one table with a column that is the struct identifier and then have redundant columns, but this seems wasteful.
I can have one table for each struct type. These would have a foreign key back to the master array table. But, how do I point to the struct tables?
There's really two major ways to solve this:
table-per-type
table-per-hierarchy
Either of them has its pros and cons.
Table-per-type gives you more tables (one per type), which only store the "delta" from the immediate super class. Worst case, you need to join together a number of tables to finally get all the data together for a single instance of a type. Pros: since you only store what's really relevant for that type into a separate table, you can do this like set NOT NULL restrictions etc. on the database table.
Table-per-hierarchy gives you less tables, but each table represents an entire hierarchy, so it will contains potentially lots of columns which aren't filled (in the rows representating base class types). Also, on the extra columns that make up the derived classes, you cannot set things like NOT NULL restrictions - all those extra columns must be nullable, since they really don't exist in the base classes, so you loose some degree of safety here.
See for yourself - there are two really good articles on how to do this (in Entity Framework, but the principles apply to any database and any data mapping technology):
Demystifying The Code: Table Per Type
Demystifying The Code: Table Per Hierarchy
Hope this helps and gives you some inputs!
Marc
I do the "table-per-sublcass" style from the Hibernate docs.
You make a Person table with all the things you know about a person, plus the PersonID. Then you make a Customer table, with only the data that's unique to a Customer (account balance, etc). Put the PersonID in the Customer table. A WebsiteUser might have a CustomerID in it, and so on down the chain.
One-to-one relationships mapping the IS-A inheritance relationships.
One possibility is an XML field to store the data, this allows searching and retrieving whilst also being relatively easy to serialise. (the question says SQL, but doesn't specify a specfic vendor database, so XML may not work for every DB solution.)
Edit : I'm going to caveat this because it's not entirely clear what needs to be stored / retrieved / purpose etc, so XML may be entirely inappropriate - I'm throwing it out there as a thought provoker instead.

Fluent Nhibernate and Dynamic Table Name

I've got a parent and child object. Depending on a value in the parent object changes the table for the child object. So for example if the parent object had a reference "01" then it will look in the following table "Child01" whereas if the reference was "02" then it would look in the table "Child02". All the child tables are the same as in number of columns/names/etc.
My question is that how can I tell Fluent Nhibernate or nhibernate which table to look at as each parent object is unique and can reference a number of different child tables?
I've looked at the IClassConvention in Fluent but this seems to only be called when the session is created rather than each time an object is created.
I found only two methods to do this.
Close and recreate the nhibernate session every time another dynamic table needs to be looked at. On creating the session use IClassConvention to dynamically calculate the name based on user data. I found this very intensive as its a large database and a costly operation to create the session every time.
Use POCO object for these tables with custom data access.
As statichippo stated I could use a basechild object and have multiple child object. Due to the database size and the number of dynamic table this wasn't really a valid option.
Neither of my two solutions I was particularly happy with but the POCO's seemed the best way for my problem.
NHibernate is intended to be an object relational mappers. It sounds like you're doing more of a scripting style and hoping to map your data instead of working in an OOP manner.
It sounds like you have the makings of an class hierarchy though. What it sounds like you're trying to create in your code (and then map accordingly) is a hierarchy of different kinds of children:
BaseChild
--> SmartChild
--> DumbChild
Each child is either smart or dumb, but since they all have a FirstName, LastName, Age, etc, they all are instances of the BaseChild class which defines these. The only differences might be that the SmartChild has an IQ and the DumbChild has a FavoriteFootballTeam (this is just an example, no offense to anyone of course ;).
NHibernate will let you map this sort of relationship in many ways. There could be 1 table that encompasses all classes or (what it sounds like you want in your case), one table per class.
Did I understand the issue/what you're looking for?

How to map many columns from one table in database to one array/list in class?

I have a table in database which has some columns like year,name and also 12 columns (m1,m2,...,m12) representing months. I would like to map this table into one class using NHibernate, ideally, these 12 mapped columns would look like:
_mappedMonths[] = new double[12];
Has anyone a solution for this ?
If you really want to map the columns directly to an array, as you describe, take a look at the ICompositeUserType interface. You can find an article about custom NHibernate mapping here, and this blog post might be of interest as well.
However, if it is not super important you might consider mapping the columns just as you normally would, but as private/protected properties, and then create a public property in your class that exposes those private/public properties as an array. That would be a simpler and faster solution, but would result in code that is not quite as clean.

Enum tables in Hibernate/NHibernate

We are using NHibernate, and one of the common patterns we have for storing enum-like information is to define separate tables for the enum, and just make a reference to the ID in the main entity/table that uses the enum. A simple example:
Message
-------
ID (bigint PK)
MessageTypeID (bigint FK)
Body (varchar)
MessageType
-----------
ID (bigint PK)
Value (varchar)
The MessageType table contains a small number of enum values like: SMS, MMS, PSMS, etc.
Is it worth putting enum values in separate tables like this? I guess the pro of the enum is that you can more easily extend it in the future and it's more normalized, but the con is that you have to do a join every time you fetch a Message. Is there a breaking point where you would choose one over the other?
Using enums implies to do not use another table as you are doing right now. It's also faster as you said and so much simpler.
In both cases you can add more options, but the question is: if you add another item in the table are you going to need to recompile the application to add such feature?
I mean, if your application design is coupled and to support a new message type you need to recompile (maybe because you need to include the SMS implementation), it's not worth it to have a separate table, and you should use enums
On the other side, if either your entity lacks of logic (such a Countries, or States table), or your application can plug in a new message type without recompile you should use another table. For this, you could change your table to something like this:
MessageType
-----------
ID (bigint PK)
Value (varchar)
ImplementationType (varchar) (ie: Xyz.SMSSender, Xyz)
Or you could have a separated configuration file, where you can customize the injected dependencies.
I would create a enum in your code with matching ID to your MessageType table. Then on your classes just use that and nHibernate should be able to map it properly.
I've been straying from enum tables, especially when that data does not need to be managed data. Are you going to be adding more and more MessageType's as you go?