Controlling DBML EntityRef creation in DBML with multiple foreign keys - linq-to-sql

Using Linq to SQL and the autogeneration capabilities of DBML, foreign key relationships create EntityRefs in the DBML designer file. For example :
private int _USStateId;
private EntityRef<USState> _USState;
However, if I have the need for a table with numerous FK relationships to the same table, how can i control the autogenerated names? For example, for a Car survey with three FKs into a Ratings table, I get
private int _BodyRatingId;
private int _ColorRatingId;
private int _PerformanceRatingId;
in my Car table with
private EntityRef<Rating> _Rating;
private EntityRef<Rating> _Rating1;
private EntityRef<Rating> _Rating2;
How can I, dynamically or other wise, control the EntityRef naming to indicate that they pertain to a particular field?
Thanks!

Hi
I'm not sure if the question is still valid but in case anybody needs it:
You can add a partial class to your project with the same name as your Car table and add new properties:
public Rating BodyRating
{
get
{
return this._Rating.Entity;
}
}

Related

SQLGrammar error when querying MySql view

When a run a GET request i get an exception o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'disburseme0_.reason_type' in 'field list' in stack trace even though i have configured the field correctly in the entity class. I have a Spring Boot SOAP interface that is querying a MySql database view. I have assigned one of the unique keys from the parent tables as the view Id in JPA.
Part of my entity class has:
#Entity
#Table(name="disbursement_payload")
public class Disbursement {
#Id
#Column(name="ID")
private long disbursementId;
#Column(name="ReasonType")
private String reasonType;
public long getDisbursementId() {
return disbursementId;
}
public void setDisbursementId(long disbursementId) {
this.disbursementId = disbursementId;
public String getReasonType() {
return reasonType;
}
public void setReasonType(String reasonType) {
this.reasonType = reasonType;
}
I have the view as:
CREATE VIEW disbursement_payload AS (
SELECT
iso_number AS Currency,
trans_desc AS ReasonType,
account_number AS ReceiverParty,
amount AS Amount
FROM m_payment_detail, m_loan_transaction
WHERE m_payment_detail.`id`= m_loan_transaction.`payment_detail_id` AND
m_payment_detail.`payment_type_id`=2
);
Is there something im missing , in the entity or view definition? I have read one of the comments here could not extract ResultSet in hibernate that i might have to explicitly define the parent schemas. Any assistance, greatly appreciated.
do the mapping for db column and class var name based on camelCase conversion basded on underscore _ separated name
you could try using
CREATE VIEW disbursement_payload AS (
SELECT iso_number AS currency
, trans_desc AS reason_type
, account_number AS receiver_rarty
, amount AS amount
FROM m_payment_detail
INNER JOIN m_loan_transaction
ON m_payment_detail.`id`= m_loan_transaction.`payment_detail_id`
AND m_payment_detail.`payment_type_id`=2
);
the view code is SQL code and hibernate see a view as a table, so the conversion of column name is base on the same rules
and a suggestion you should not use (older) implicit join based on where condition you should use (more recent) explici join sintax ..

mysql : why would I require AttributeConverter over enum to map a DB column having enum datatype as enum with a JPA entity?

I am having a user database table as:
CREATE TABLE IF NOT EXISTS `user` (
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`first_ name` VARCHAR(45) NOT NULL,
`active_status` ENUM('ACTIVE', 'PENDING', 'DEACTIVATED', 'BLOCKED', 'SPAM', 'DELETED') NOT NULL ,
UNIQUE INDEX `unique_id_UNIQUE` (`unique_id` ASC),
UNIQUE INDEX `email_UNIQUE` (`email` ASC),
PRIMARY KEY (`user_id`))
ENGINE = InnoDB;
I mapped it to a corresponding JPA entity class as:
#Entity
public class User implements OfloyEntity {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
private int userId;
//other fields
#Enumerated(EnumType.STRING)
#Column(name = "active_status", nullable = false, length = 11)
private UserStatus activeStatus;
As you can see, I have mapped activeStatus to a enum UserStatus to restrict the entires from persistence layer itself.
public enum UserStatus {
ACTIVE,
PENDING,
DEACTIVATED,
BLOCKED,
DELETED,
SPAM
}
I want to know is there any drawback of using this approach for implementing a DB enum in persistence layer? I gone throw multiple articles which recommend using AttributeConverter but since the the values in my enum are very limited and have less chances of modification, I am unable to relate all those articles with my requirement.
Is there something I am missing, or any improvement can be done in my design?
Articles I gone throw:
vladmihalcea
thorban and some other stackoverflow questions.
Update: After reading the answer from Jens, I decided to implement AttributeConverter(for user's gender). And that confused me a little:
Why I decided to use enum as MYSQL column type : as it restrict the values and require less space. Because MYSQL stores the ordinal value of it's enum behind the scene and when asked for the value it represents the String value of that, it saves space.
My implementation of gender:
public enum UserGender {
MALE('M'),
FEMALE('F'),
OTHER('O');
private Character shortName;
private UserGender(Character shortName) {
this.shortName = shortName;
}
public Character getShortName() {
return shortName;
}
public static UserGender fromShortName(Character shortName) {
switch (shortName) {
case 'M': return UserGender.MALE;
case 'F' : return UserGender.FEMALE;
case 'O' : return UserGender.OTHER;
default:
throw new UserGenderNotSupportedException("user gender with shortName : " + shortName + " not supported");
}
}
}
converter class:
#Converter(autoApply = true)
public class UserGenderConverter implements AttributeConverter<UserGender, Character> {
#Override
public Character convertToDatabaseColumn(UserGender userGender) {
return userGender.getShortName();
}
#Override
public UserGender convertToEntityAttribute(Character dbGender) {
return UserGender.fromShortName(dbGender);
}
}
Now, the major doubts:
1. As per blogs, using MYSQL enum is evil in DB, because someday if I need to add extra values to the enum column and that would require a table ALTER, but isn't it the same case with using AttributeConverter? Because there also we use a java enum, which would need to be change if someday new genders are required?
2. If I use AttributeConverter, I would have to document java enum(UserGender here) explaination somewhere so that DBA can understand what F,M,O stands for. Am I right here?
The articles gave you a rich selection of potential drawbacks:
Using #Enumerated(EnumType.STRING) has the following:
It uses lots of space compared to other options. Note that means more data needs to be loaded and transferred over the wire this has an effect on performance as well. We have no idea if this is a problem for you and you won't know either until you made some performance tests.
Ties the name of the enum values hard to the column values. Which can be risky since developers are used to renaming stuff quickly and you would need tests with actual legacy data to catch this.
If you don't work with really huge amounts of data for which updating the column for all rows is an actual problem, I wouldn't sweat it. It's easy enough to introduce an AttributeConverter and update the data when the simple solution actually becomes a problem.
Update regarding the updated question:
I don't buy into the argument that anything is "evil" because it might require an ALTER TABLE statement. By this argument, we should abolish relational databases completely because using them requires DDL and evolution of an application will require more of it. Of course, the necessity of a DDL statement makes a deployment a little more complex. But you need to be able to handle this thing anyway.
But it is true that with an AttributeConverter you wouldn't need any DDL in this case, because you'd just put another value in the same column which doesn't have any special constraints except the maximum length of the value. This assumes you don't have a check constraint on the column to limit the legal values.
Do you have to document the relationship between Enum and the value stored in the DB? Depends on your team. Does the DBA even care about the meaning of the data? Does the DBA have access and the skills to understand the Java code? If the DBA needs or wants to know and can't or won't get the information from the source code you have to document it. True.

Code First Primary key auto increment with a prefix

I have a database issue. well im not sure exactly what to do. Im using the codefirst approach in an mvc5 project.
Currently my primary keys for my tables are auto generated and they increase. eg. customerid - 0,1,2,3 etc.
I want to know, how do i add a prefix to this id, eg i want it to be Cust0 instead of just 0.
The question is what is the reason you want to have this kind of "key"? You can auto generate ID for your customer and create your own property:
public class Customer
{
public const string CustomerPrefix = "Cust";
[Key]
public int Id {get; set;}
[NotMapped]
public string CustomerId
{
get { return string.Concat(CustomerPrefix, Id)}
}
}
Btw.: It is really bad practice to have PK as a string (because of performance)

Using LongListSelector with a Deployed Database

I'm trying to create an app for Windows Phone 8 that displays data in a LongListSelector that's populated from a SQL CE database that's shipped with the app. I think I have the opening and reading from the database functions down, but I can't correctly use LINQ to SQL to group the data for the LLS.
I've got a database class with a table and corresponding columns. I'm using a helper class "KeyedList" to add a public name for the data from msdn sample code:
public class KeyedList<TKey, TItem> : List<TItem>
{
public TKey Key { protected set; get; }
public KeyedList(TKey key, IEnumerable<TItem> items)
: base(items)
{
Key = key;
}
public KeyedList(IGrouping<TKey, TItem> grouping)
: base(grouping)
{
Key = grouping.Key;
}
}
Then I've got my database context:
dB = new DataContext(DataContext.DBConnectionString);
Finally, here's the LINQ to SQL I'm trying to use:
var items =
from item in dB.TableName
orderby dB.ID
group item by dB.Generation into generation
select new <KeyedList<string,Item>(generation);
var allItems = new List<KeyedList<string, Item>>(items)
I've pretty much taken this code from the sample, but I can't get the grouping and ordering to work when creating allItems for binding to the LongListSelector. I keep getting invalid arguments error.
I'm very new at VB programming and appreciate all the help!
I found the issue. When creating the new Keyed list make sure to use the correct key type and item type. The key type will be the type of the data used by group by, and the item type is your DataContext. So in my case db.Generation is a string and the DataContext type is of type Item.

Getting the ID (PK) of a newly persisted entity

I'm developing a J2EE 6 Web Application, using a MySql 5.02 DataBase. I'm trying to generate a hash digest of the ID, every time I create a new Entity. This is set to a column on the Table.
But well, I'm stuck on something that is apparently easy, and according with what I found googling, possible. Basically I want to retrieve the ID (Primary Key) of a newly persisted object, but whatever I try, it returns null.
The steps are follow are:
Create the Instance of the Entity -> userCard = new Users();
Setting the corresponding fields with some values.
Calling the persist() method of the EntityManager.
After reading some forums, I understood I had to either call flush() after persist(), or use merge() and use the returned entity to retrieve the id.
public void createAndFlush(Users users) {
em.persist(users);
em.flush();
}
public Integer edit(Users users) {
return ((Users)em.merge(users)).getIdvcards();
}
None of them (among some other combinations) work, well, the Entity is successfully persisted, but the ID field returns null.
These are the correspinding annotations of the id column I want to retrieve:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idvcards")
private Integer idvcards;
And obviously, the column idvcards of my table is set to Auto-Increment and Primary Key.
Maybe I just need to clarify my Peristence-Management concepts, but I'd appreciate if I can get some hint to solve this basic issue.
Maybe is not the most elegant solution ever, but finally I succeded on retrieving the ID of the new Entity:
public Integer create(User user) {
em.persist(users);
em.flush();
return (Integer) em.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(users);
}
And well, althought is not related to the functionality, I changed the entity name to the singular form as #Bohemian suggested.
Try this, it works for me:
#Id
#GeneratedValue
#Column(name = "id", unique = true, nullable = false)
Also, I don't use the value returned from merge. I just persist then flush and the entity object magically gets the new key value.
p.s. Tables should never be named in the plural, and especially not the entity class. Call the class User (and the table if you can). Otherwise it's just confusing: Users sounds like a collection of User.
It will work fine
em.persist(usmApproveTransaction);
em.flush();
System.out.println("++++++e++++++++"+usmApproveTransaction.getUatApproveTransIdPk());
return usmApproveTransaction;
I'm getting id using em.flush(); after persist
++++++e++++++++51472