Create long types in JPA entities - jpa

I'm trying to generate JPA entities from tables using eclipse plugins, I defined some BIG INT and Date columns. I would like to have long type in Entity class for those BIGINT columns, But It generates as String. Please help me how to resolve it?

Sounds really weird that the Eclipse plugin generates those columns as String - check that you haven't missed / misread something.
If the column really is a BIG INTEGER in the database, just changing the type of the property field to Long should do the trick.

I don't know exactly what do you mean long properties, but try to use #Type annotation. Example:
#Type(type = "org.hibernate.type.LongType")

Related

How to add defaults to existing columns with Gorm

I'm using gorm and have a model like so:
type MyModel struct {
CreationTime time.Time
UpdateTime time.Time
}
I realized after deploying my DB that creation time and update time weren't adding times when items were being created and updated! I tried to fix this by updating the model to the following:
type MyModel struct {
CreationTime time.Time `gorm:"default:current_timestamp"`
UpdateTime time.Time `gorm:"default:current_timestamp ON update current_timestamp"`
}
However, auto migrating like the following won't apply these defaults on the already existing tables!
db.AutoMigrate(&MyModel{})
Is there any way I can use the built in migration functions to add defaults to columns? I searched the docs and it seems like I can only change the type of existing columns! If not, any recommendations for a why to simply add defaults to a column via migrations?
Have you tried sql tag?
`sql:"DEFAULT:current_timestamp"`
The automigration provided by gorm doesn't delete or modify your columns and for good reasons, it's not safe.
I had a similar issue. I needed to drop the null constraint from one of my columns and couldn't find anything that does that in gorm, and I'm pretty sure it doesn't. I wrote my own function for doing this. You can easily do something similar.
Please take a look at these two commits: this and this. What you can basically do this is to define a method for the Dialect interface and then write an implementation for that method for the commonDialect type (and the postgres type, if required).
Hope this helps. Feel free to ask me if you face any problems with implementation or have any doubts.

Setting JPA behavior for importing entities from tables

How can I tell JPA how to behave with different column types in my database when it tries to generate the entities from tables?
For example when I have a column like the following in my MySQL:
`deleted` tinyint(1) NOT NULL DEFAULT 0,
I want in the generated entity by JPA have boolean instead of byte, but what the JPA will generate is something like this:
#Column(nullable=false)
private byte deleted;
However I want to have something like this:
#Column(nullable=false)
#Type(type = "org.hibernate.type.NumericBooleanType")
private boolean deleted;
I think there must be a way that I tell JPA how to translate the column types in my tables in the entities in Java!?
I don't like to modify the entities by hand!
If you're asking how to configure the Eclipse wizard to map TINYINT onto boolean, the answer is you probably cannot.
Using Hibernate tools looks more promising, though. There's a hibernate.reveng.xml config file you can use to control type mapping.
As a side note:
I don't like to modify the entities by hand!
Note that reverse engineering tools in general lack the business knowledge required to generate a business model structure that is completely sensible. You will likely have to do some tweaking (e.g you likely won't get any #ManyToMany associations, even if they are the more natural solution domain-wise).
In the last page of that wizard we can define the expected type for each column. The interesting part is, eclipse stores somehow the selected types for each column and in the future when you try to regenerate the entities you don't need to do this step times to times!

How to Use inheritance in EF

I am using EF 4.0 , i have one problem
Table structure in DB is:
Table: Setting--->
Name (PK)
GroupBy
DataType
Table: UserSetting-->
SettingName(PK)(FK)
UserName(PK)(FK)
Value
Table: WorkstationSetting-->
SettingName(PK)(FK)
WorkstationName(PK)(FK)
Value
Now i want to make use of inheritance, because WorkstationSetting and UserSetting inherits settings so any suggestion how to achieve inheritance, i tried but i got error like
"Error 39 Error 3003: Problem in mapping fragments starting at line 1621:All the key properties (Settings.Name) of the EntitySet Settings must be mapped to all the key properties (WorkstationSetting.SettingName, WorkstationSetting.WorkstationName) of table WorkstationSetting.
I see you have in UserSetting and WorkstationSetting a composite PK.
If UserSetting and WorkstationSetting are derived from Setting, they should have Name as PK.
Another comment; in general, it's not recommended to use a name or something "meaningful" as PK since it is less scalable and might cause limitations (i.e. max index size). Use instead an int or uniqueidentifier.
I recommend you to introduce a new field which is SettingId which should be added to all three tables. In EF designer, just add the Inheritance.
Look into table per type inheritance. For example look here. It should help you get started. The idea is that you have a table for each concrete type (as you have) and you map it to an object hierarchy.
Maybe your problem is with the keys. How is your mapping defined? Are the associations between the tables defined in the DB?

MyBatis mapping properties to database columns when inserting & updating (using annotations)

I'm just starting to learn MyBatis and I'm wondering, when I'm creating insert or update queries, is there a way that I can make property names a bit more friendly to refactoring? I'll explain in more detail:
I have constants in all of my domain classes that can be used to reference property names. In my opinion, it cuts down on typos and makes refactoring a bit easier.
public static final String FIRST_NAME = "firstName";
private String firstName = "";
When I create a MyBatis select statement using annotations, I can do something like this:
#Select("SELECT ID, FIRST_NAME, LAST_NAME FROM CUSTOMERS WHERE ID = #{id}")
#Results({
#Result(property = CustomerDetail.ID, column = "ID"),
#Result(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
#Result(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
CustomerDetail selectById(final int id);
If I refactor my domain object (CustomerDetail) and change property names, it ends up being fairly simple.
However, when I create a MyBatis insert statement using annotations, I have to do something like this:
#Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME) VALUES (#{id}, #{firstName}, #{lastName})")
void insertCustomerDetail(final CustomerDetail customerDetail);
In this case, if I refactor my domain object (CustomerDetail) and change property names, it's much more error prone. Is there a way I can use my constants without resorting to a bunch of string concatenation? Is it something I should even concern myself with?
As a total newbie, I was expecting the #Insert and #Update annotations to mimic the structure of the #Select annotation. For example (please note, the below are NOT valid MyBatis annotations):
#Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME)")
#Params({
#Param(property = CustomerDetail.ID, column = "ID"),
#Param(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
#Param(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
void insertCustomerDetail(final CustomerDetail customerDetail);
Have I missed any options that would have the same effect as my above sample? Alternatively, is it possible for me to unit test MyBatis mappings to ensure no one is using property names that don't exist in my domain objects? Testing may be a better solution since it would also apply to XML based mappings. Thoughts?
Is it something I should even concern
myself with?
I don't think so. I understand your concern, and I see how such a feature could be beneficial to you, especially early in development when POJO's tend to change so often.
I don't think your objects fields will be refactored enough to justify the investment needed to provide this functionality.
I suggest you read about the #Param tag in the mybatis user guide. It's not exactly what your looking for here, but it is a way to decouple object field names to mybatis sql map variables. In my mind, I would take your approach over passing in individual feilds with a #Param.
In regards to unit testing your sql maps, i'm fairly certain that if you use an ognl expression that doesn't have a corresponding get method in the object you'll get an exceptions. i.e if you use #{someField}, and the object your passing in doesn't have a getSomeField() method, then you get exception.

Object cannot be cast from DBNull to other types Entity Framework

I've got a column in one of my models that is nullable. It is nullable in the EDMX, and I've checked that it's nullable in the generated code. I've octuple-checked that it's nullable in the database. However, when I try to save an instance of the model with the column set to null, I receive the exception "Object cannot be cast from DBNull to other types." Most of the code involved here is either the Entity Framework code itself, or generated code. I have other nullable columns that do not seem to have this problem.
Has anyone run into anything like this? Googling around for things mostly reveals people who need to do if (someSqlValue == DBNull.Value) with manual ADO recordsets, but since this is EF interacting with DBNull, there's nowhere in my code that could possibly need to check this.
Unfortunately, I cannot share the code with this, and as I mentioned, most of my nullable columns do not exhibit this problem, so I am not confident in my ability to reproduce the problem in a small test case.
Have you checked that the type in your EDMX matches the type in your database (i.e. that you aren't trying to stuff a null int SQL value into a nullable DateTime field or something like that)?