Java for Web Learning Notes (111): Talk about entity mapping (4) Dynamic table creation __java

Source: Internet
Author: User
Tags getmessage rollback sql error

If this uncertainty table also needs our war to create, how to achieve. The native sql,entitymanager of the CREATE table cannot be performed because it is not a transaction that can be rolled back. In this case, we need to: capture an exception that does not exist in the table to implement table creation from the original connection.

getting connection to get connection from Entitymanage relies on the concrete implementation of JPA, which is supported by eclipse, but Hibernate is not supported.

Can be obtained through unwrap, unfortunately hibernate does not support
Connection conn = Entitymanager.unwrap (connection.class);
If we need to use the Hibernate proprietary API, we can take advantage of unwrap () to get hibernate session sessions
= Entitymanager.unwrap ( Session.class);

Blocked, we need to get from the datasource.

throw an exception when you need to create a table

public class Wantcreatetableexception extends runtimeexception{

	private static final long serialversionuid = 1L;

	Public wantcreatetableexception (String message) {
		super (message);
	}
}
Modify the code for the warehouse
@Repository @Validated public class Eventrepository {private static final Logger log = Logmanager.getlogger ();
	private static final Gson Gson = new Gson ();
	@PersistenceContext private Entitymanager Entitymanager;
	
	@Inject private DataSource DataSource;  private static final String Create_table_sqlformat = "CREATE TABLE IF not EXISTS '%s ' (" + "' ID ' bigint () unsigned not
	NULL auto_increment, "+" ' Data ' text, "+" PRIMARY KEY (' id ') "+") Engine=innodb DEFAULT Charset=utf8 ";
		public void CreateTable (string tablename) {String sql = String.Format (Create_table_sqlformat, TableName);
				Try (Connection conn = Datasource.getconnection ();
		PreparedStatement PS = conn.preparestatement (sql);) {ps.execute ();
		}catch (SQLException e) {log.error ("(SQL error) Try to create TABLE {} error: {}", TableName, e.tostring ());
	
	}} private String Gettablename () {...}
		Public EventData FindOne (Long id) {log.traceentry ();
	String tablename = Gettablename ();	try{String sql = String.Format ("Select * from '%s ' WHERE ' id ' =?", Tablename,id); Return Eventdata.build (evententity) entitymanager.createnativequery (Sql,evententity.class). SetParameter (1, id).
		Getsingleresult ());
		}catch (Exception e) {return null; } public void Save (EventData event) {try{if (event.getid () = null | | Event.getid () = 0) This.insert (event
			);		
		else This.update (event);
			}catch (Exception e) {if (Istablenotexist (E, Gettablename ())) throw new Wantcreatetableexception (Gettablename ());
		else throw e;
	
	} Private Boolean update (EventData data) {...}

	private void Insert (EventData data) {...} Private Boolean istablenotexist (Exception e,string tablename) {if (e.getcause () = null | | e.getcause (). Getcause () = nul
		L) return false;
		String message = E.getcause (). Getcause (). GetMessage ();
	return stringutils.contains (Message, Tablename.concat ("' doesn ' t exist")); }
	
}
Use examples
@Service public
class Testservice {
	@Transactional public
	void Test2 () {
		EventData event = new EventData ();
		Event.adddata ("hello,world!");
		This.eventRepository.save (event);
	}

The following is just a test example, we call the warehouse in controller, this is not really good, controller should only call service, we can have a business logic service in the middle, its call Testservice to complete the relevant processing. @Transactional will exit the transaction in the face of RuntimeException, and the transaction is in the form of a proxy, that is, internal calls in this class do not work.

@Controller public
class TestController {
	@Inject testpageservice testservice;
	@Inject eventrepository eventrepository;
	private void MyTest () {
		try{
			testservice.test2 ();
		} catch (Wantcreatetableexception e) {
			this.eventRepository.createTable (e.getmessage ());
			Testservice.test2 ();}}

I tried to write as follows, but failed.

This has no effect, will still report transaction was marked for rollback only; Cannot commit;
My understanding is that wantcreatetableexception is just my encapsulated exception, and the source of the exception, has been triggered at the hibernate bottom of the rollback:
//serious: Servlet.service () for servlet [Springwebdispatcher] in context with path [/chapter22] threw exception 
//[Request processing failed; nested Exception is org.springframework.orm.jpa.JpaSystemException: 
//Transaction were marked for rollback only; cannot Commit Nested exception is org.hibernate.TransactionException: 
//Transaction were marked for rollback only; cannot commit] wi th root cause
@Transactional (norollbackfor = wantcreatetableexception.class) public 
void Test2 () {
	EventData event = new EventData ();
	Event.adddata ("hello,world!");		
	try{
		This.eventRepository.save (event);
	} catch (Wantcreatetableexception e) {
		this.eventRepository.createTable (e.getmessage ());
		This.eventRepository.save (event);
	}
RELATED links: My professional Java for WEB applications related articles


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.