0

Lets assume I have the following domain model:

users
----
id (PK)
partitionkey (PK)

In the above table, the partition key is primarily used for partitioning. (MySQL requires the partitionkey to be part of the primary key). If we assume the record can be uniquely identified by the id field only, is there any harm in skipping partitionkey in the mapping. For example, is the mapping below valid:

@Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public Long id;

    @Column(name="partitionkey")
    private Long partitionKey;

}
SKP
  • 49
  • 1
  • 1
  • 5
  • what's the name of your table? – Abdelhak Feb 02 '16 at 12:03
  • @SKP, if the answers are what you want, please accept one of them (at least upvote the other). You cannot accept both, but you can upvote both. That's a fair way to do if the answer is what you want. If it's not, could you provide us with some more information of what you want? :) – Paulo Feb 02 '16 at 12:42
  • @Paulo , the table name was a typo (have fixed that). Sorry about that. The main intention of the question is to understand if the mapping needs to strictly correspond to the database. In this case, can the database have a composite primary key defined, but the mapping only define one of the fields in the composite primary key as **@Id**, that is the DB defines id, partitionkey as the primary key, but only id is marked with **@Id** in the mapping – SKP Feb 02 '16 at 13:39
  • Yes, the mapping has correspond strictly to the database. If you have two columns to indicate the primary key, you have to indicate that in your java class. – Paulo Feb 02 '16 at 14:52

2 Answers2

0

Try to define a separate @Embeddable object with the PK fields and use it as @EmbeddedId in your @Entity class like this:

  @Embeddable
  public class MyCompositePK { 

  @Column(name="id")
  private Long id;

  @Column(name="partitionkey")
  private Long partitionKey;
   }

   @Entity
   @Table(name = "users")
   public class User implements Serializable {

    @EmbeddedId
    private MyCompositePK id;
    ...

  }
Abdelhak
  • 8,299
  • 4
  • 22
  • 36
  • Any reason for that change? That is not what OP asks. – Aleksandr M Feb 02 '16 at 12:28
  • The name is different in db with table annotation @AleksandrM – Abdelhak Feb 02 '16 at 12:29
  • That is what OP asked. As you can see in question's title: "JPA mapping **not matching** database". It's not matching because of what @Abdelhak answered. – Paulo Feb 02 '16 at 12:31
  • *If we assume the record can be uniquely identified by the id field only, is there any harm in skipping partitionkey in the mapping. For example, is the mapping below valid* – Aleksandr M Feb 02 '16 at 12:32
  • 1
    The table name mismatch was a typo (sorry about that), have fixed that and added a comment in reply to clarify my question. – SKP Feb 02 '16 at 13:42
  • @SKP can explain more the issue do you have – Abdelhak Feb 02 '16 at 13:49
0

Yes, it's valid. JPA provider is not aware of any constraints or other features that exist in the tables to which entities are mapped.

However, is it a good approach, especially because we're talking about partitioning here? Keep in mind that entities are associated via ids. So, for each entity that is associated with User, JPA provider will search the associated User instance by id column only, thus partitioning column will not be included in the query. This may or may not be a problem. See this answer as well for more details.

The alternative could be using provider specific extensions like @JoinFormulas in Hibernate, but they may not be easy to get right.

I would say that going with composite ids is the most straightforward solution to go.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
  • Thanks, as I understand, the issue with not mapping the partitionkey in the id would be that the queries generated may not have the partitionkey in the where clause? Can this be offset by explicitly specifying the queries using the @Query annotations and not relying on the default provided framework generated queries? – SKP Feb 02 '16 at 14:58
  • @SKP Please see my edited answer. Exactly, auto-generated queries may not contain that column in the `where` clause. – Dragan Bozanovic Feb 02 '16 at 16:34
  • Unfortunately using the composite key presents itself with other issues. The partitionkey is not nullable and hence lends itself poorly to population of parent-child entities. From what I have seen the way it works(for a new insert of parent and child), JPA implementations first do an insert with a null for the referenced column and then try to update it with the correct value from the parent (for auto-generated keys in the parent). This fails in cases where the referenced column is not nullable(in this case the partition key). Hence my question about ignoring the non-nullable columns. – SKP Feb 03 '16 at 04:50
  • If you make the mappings correctly, it should not insert nulls. Please see [my comment](http://stackoverflow.com/questions/35143661/spring-data-jpa-delete-child-entities-instead-of-setting-to-null-on-update/35159891?noredirect=1#comment58062850_35159891). – Dragan Bozanovic Feb 03 '16 at 09:14