views:

162

answers:

2

My scenario is as follows:

  • I have some objects (Messages) that can be tagged
  • So I have a Tag entity and many-to-many relationship
  • The above is done and working
  • Now, when tagging, I'd like to save new tags only if they don't exist (where existence is checked by tag title)
  • if the tag already exists, I'd like it to be recognized and attached to my object instead of a new one

What is the easiest/cleanest way to do it?

BTW, for some reasons I'd like to use artificial primary key (numeric Id) for my Tag entity.

Thanks!

A: 

Just to clarify - a Tag can be pinned on many Objects, and an Object can have many Tags. That's what a many-to-many relationship means to me. Is that how you mean it?

When you do this in SQL, you have tables named TAG and OBJECT and a join table named TAG_OBJECT that contains two columns, one for each primary key in the other tables. The primary key in the TAG_OBJECT join table is the pair (TAG_ID, OBJECT_ID). That guarantees a unique pairing for each row.

If you're using Hibernate, you just add a list or collection of Objects as a private data member to your Tag class, and a list or collection of Tags as a private data member to your Object class.

I think Hibernate will handle your "only if it doesn't exist", as long as you write a good method to determine "deep equality" between two instances of Tag.

You should also add a unique constraint to the tag title attribute. Here's an example that doesn't quite fit your needs, because it's Java and XML, but perhaps that hint will be enough to tell you where to look for NHibernate:

<element column="serialNumber" type="long" not-null="true" unique="true"/>

For your case, the column will be the tag title, type is string, and the other flags remain as they are in the example.

duffymo
Yeah, that's what I mean. The relationship part is done and working, now I'm trying to make tags unique. For the sake of further discussion, let's say the objects I'm tagging are Messages - it's just one type of entity.
Michał Chaniewski
I think Hibernate will manage this. Perhaps you need to add a unique constraint on the title attribute.
duffymo
It works in a such way, that it causes an exception to be thrown when uniqueness is broken. I can handle this, but I'm looking for a cleaner way...
Michał Chaniewski
What would "cleaner" look like? That's how Hibernate does it. If you want something else to happen you'll have to find another technology.
duffymo
+1  A: 

You have a many-to-many relationship that you can express in your business classes and map with NHibernate. The structure of the linking table that resolves the many-to-many relationship will prevent an object from being linked to the same tag more than once.

The only way to enforce the rule in your question is through code. The sequence of tasks would be something like:

  1. Parse user entered tag list into individual tags
  2. Loop through tags ...

    a. If a tag exists then add it to the object's tags collection

    b. Else create a new tag and add it to the object's tag collection

  3. Persist object

You will need to add logic to look for existing tags taking into account spelling mistakes, capitalization, and alternate usage. For example you don't want to have tags that mean they same thing but do are not equal strings, such as "ASPNET" or "ASP.NET" or "asp.net". The quality of your tag list will depend on how robust the code that checks for existing tags is.

Jamie Ide